LCOV - code coverage report
Current view: top level - basebmp/source - bitmapdevice.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 694 0.0 %
Date: 2014-04-14 Functions: 0 1086 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <sal/config.h>
      21             : 
      22             : #include <cassert>
      23             : #include <string.h>
      24             : 
      25             : #include <basebmp/bitmapdevice.hxx>
      26             : 
      27             : #include <basebmp/compositeiterator.hxx>
      28             : #include <basebmp/iteratortraits.hxx>
      29             : 
      30             : #include <basebmp/accessor.hxx>
      31             : #include <basebmp/accessortraits.hxx>
      32             : #include <basebmp/accessoradapters.hxx>
      33             : #include <basebmp/colorblendaccessoradapter.hxx>
      34             : 
      35             : #include <basebmp/color.hxx>
      36             : #include <basebmp/colormisc.hxx>
      37             : #include <basebmp/colortraits.hxx>
      38             : 
      39             : #include <basebmp/greylevelformats.hxx>
      40             : #include <basebmp/paletteformats.hxx>
      41             : #include <basebmp/rgbmaskpixelformats.hxx>
      42             : #include <basebmp/rgb24pixelformats.hxx>
      43             : 
      44             : #include <basebmp/scanlineformats.hxx>
      45             : #include <basebmp/fillimage.hxx>
      46             : #include <basebmp/scaleimage.hxx>
      47             : #include <basebmp/clippedlinerenderer.hxx>
      48             : #include <basebmp/polypolygonrenderer.hxx>
      49             : #include <basebmp/genericcolorimageaccessor.hxx>
      50             : 
      51             : #include <basebmp/tools.hxx>
      52             : #include "intconversion.hxx"
      53             : 
      54             : #include <rtl/alloc.h>
      55             : #include <osl/diagnose.h>
      56             : 
      57             : #include <basegfx/tools/tools.hxx>
      58             : #include <basegfx/tools/canvastools.hxx>
      59             : #include <basegfx/range/b2ibox.hxx>
      60             : #include <basegfx/range/b2irange.hxx>
      61             : #include <basegfx/range/b2drange.hxx>
      62             : #include <basegfx/polygon/b2dpolygon.hxx>
      63             : #include <basegfx/polygon/b2dpolygontools.hxx>
      64             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      65             : #include <basegfx/point/b2ipoint.hxx>
      66             : #include <basegfx/vector/b2ivector.hxx>
      67             : 
      68             : #include <vigra/iteratortraits.hxx>
      69             : #include <vigra/rgbvalue.hxx>
      70             : #include <vigra/copyimage.hxx>
      71             : #include <vigra/tuple.hxx>
      72             : 
      73             : 
      74             : namespace vigra
      75             : {
      76             : 
      77             : /// componentwise xor of an RGBValue (missing from rgbvalue.hxx)
      78             : template< class Value, unsigned int RedIndex, unsigned int BlueIndex, unsigned int GreenIndex >
      79             : inline RGBValue<Value, RedIndex, GreenIndex, BlueIndex>
      80           0 : operator^( RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& lhs,
      81             :            RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& rhs )
      82             : {
      83             :     RGBValue<Value, RedIndex, GreenIndex, BlueIndex> res(
      84           0 :         lhs[0] ^ rhs[0],
      85           0 :         lhs[1] ^ rhs[1],
      86           0 :         lhs[2] ^ rhs[2]);
      87           0 :     return res;
      88             : }
      89             : }
      90             : 
      91             : namespace basebmp
      92             : {
      93             : 
      94             : static const sal_uInt8 bitsPerPixel[] =
      95             : {
      96             :     0,  // NONE
      97             :     1,  // ONE_BIT_MSB_GREY
      98             :     1,  // ONE_BIT_LSB_GREY
      99             :     1,  // ONE_BIT_MSB_PAL
     100             :     1,  // ONE_BIT_LSB_PAL
     101             :     4,  // FOUR_BIT_MSB_GREY
     102             :     4,  // FOUR_BIT_LSB_GREY
     103             :     4,  // FOUR_BIT_MSB_PAL
     104             :     4,  // FOUR_BIT_LSB_PAL
     105             :     8,  // EIGHT_BIT_PAL
     106             :     8,  // EIGHT_BIT_GREY
     107             :     16, // SIXTEEN_BIT_LSB_TC_MASK
     108             :     16, // SIXTEEN_BIT_MSB_TC_MASK
     109             :     24, // TWENTYFOUR_BIT_TC_MASK
     110             :     32, // THIRTYTWO_BIT_TC_MASK_BGRA
     111             :     32, // THIRTYTWO_BIT_TC_MASK_ARGB
     112             :     32, // THIRTYTWO_BIT_TC_MASK_ABGR
     113             :     32, // THIRTYTWO_BIT_TC_MASK_RGBA
     114             : };
     115             : 
     116             : namespace
     117             : {
     118             :     /** Create the type for an accessor that takes the (mask,bitmap)
     119             :         input value generated from a JoinImageAccessorAdapter, and
     120             :         pipe that through a mask functor.
     121             : 
     122             :         @tpl DestAccessor
     123             :         Destination bitmap accessor
     124             : 
     125             :         @tpl JoinedAccessor
     126             :         Input accessor, is expected to generate a std::pair as the
     127             :         value type
     128             : 
     129             :         @tpl MaskFunctorMode
     130             :         Either FastMask or NoFastMask, depending on whether the mask
     131             :         is guaranteed to contain only 0s and 1s.
     132             :      */
     133             :     template< class    DestAccessor,
     134             :               class    JoinedAccessor,
     135             :               bool     polarity,
     136             :               typename MaskFunctorMode > struct masked_input_splitting_accessor
     137             :     {
     138             :         typedef BinarySetterFunctionAccessorAdapter<
     139             :             DestAccessor,
     140             :             BinaryFunctorSplittingWrapper<
     141             :                 typename outputMaskFunctorSelector<
     142             :                          typename JoinedAccessor::value_type::first_type,
     143             :                          typename JoinedAccessor::value_type::second_type,
     144             :                          polarity,
     145             :                          MaskFunctorMode >::type > > type;
     146             :     };
     147             : 
     148             : 
     149             : 
     150             :     // Actual BitmapDevice implementation (templatized by accessor and iterator)
     151             : 
     152             :     /** Implementation of the BitmapDevice interface
     153             : 
     154             :         @tpl DestIterator
     155             :         Iterator to access bitmap memory
     156             : 
     157             :         @tpl RawAccessor
     158             :         Raw accessor, to access pixel values directly
     159             : 
     160             :         @tpl AccessorSelector
     161             :         Accessor adapter selector, which, when applying the nested
     162             :         template metafunction wrap_accessor to one of the raw bitmap
     163             :         accessors, yields a member type named 'type', which is a
     164             :         wrapped accessor that map color values.
     165             : 
     166             :         @tpl Masks
     167             :         Traits template, containing nested traits
     168             :         clipmask_format_traits and alphamask_format_traits, which
     169             :         determine what specialized formats are to be used for clip and
     170             :         alpha masks. With those mask formats, clipping and alpha
     171             :         blending is handled natively.
     172             :      */
     173             :     template< class DestIterator,
     174             :               class RawAccessor,
     175             :               class AccessorSelector,
     176           0 :               class Masks > class BitmapRenderer :
     177             :                   public BitmapDevice
     178             :     {
     179             :     public:
     180             :         typedef DestIterator                                               dest_iterator_type;
     181             :         typedef RawAccessor                                                raw_accessor_type;
     182             :         typedef AccessorSelector                                           accessor_selector;
     183             : 
     184             :         typedef typename Masks::clipmask_format_traits::iterator_type      mask_iterator_type;
     185             :         typedef typename Masks::clipmask_format_traits::raw_accessor_type  mask_rawaccessor_type;
     186             :         typedef typename Masks::clipmask_format_traits::accessor_selector  mask_accessorselector_type;
     187             : 
     188             :         typedef typename Masks::alphamask_format_traits::iterator_type     alphamask_iterator_type;
     189             :         typedef typename Masks::alphamask_format_traits::raw_accessor_type alphamask_rawaccessor_type;
     190             :         typedef typename Masks::alphamask_format_traits::accessor_selector alphamask_accessorselector_type;
     191             : 
     192             :         typedef typename AccessorSelector::template wrap_accessor<
     193             :             raw_accessor_type >::type                                      dest_accessor_type;
     194             : 
     195             :         typedef AccessorTraits< dest_accessor_type >                       accessor_traits;
     196             :         typedef CompositeIterator2D< dest_iterator_type,
     197             :                                      mask_iterator_type >                  composite_iterator_type;
     198             :         typedef CompositeIterator2D< vigra::Diff2D,
     199             :                                      vigra::Diff2D >                       generic_composite_iterator_type;
     200             : 
     201             :         typedef BitmapRenderer<mask_iterator_type,
     202             :                                mask_rawaccessor_type,
     203             :                                mask_accessorselector_type,
     204             :                                Masks>                                      mask_bitmap_type;
     205             :         typedef BitmapRenderer<alphamask_iterator_type,
     206             :                                alphamask_rawaccessor_type,
     207             :                                alphamask_accessorselector_type,
     208             :                                Masks>                                      alphamask_bitmap_type;
     209             : 
     210             : 
     211             : 
     212             :         typedef AccessorTraits< raw_accessor_type >                        raw_accessor_traits;
     213             :         typedef typename uInt32Converter<
     214             :             typename raw_accessor_type::value_type>::to                    to_uint32_functor;
     215             : 
     216             : 
     217             : 
     218             :         typedef typename raw_accessor_traits::xor_accessor                 raw_xor_accessor_type;
     219             :         typedef AccessorTraits<raw_xor_accessor_type>                      raw_xor_accessor_traits;
     220             :         typedef typename accessor_selector::template wrap_accessor<
     221             :             raw_xor_accessor_type >::type                                  xor_accessor_type;
     222             :         typedef AccessorTraits<xor_accessor_type>                          xor_accessor_traits;
     223             : 
     224             : 
     225             : 
     226             :         typedef typename raw_accessor_traits::template masked_accessor<
     227             :             mask_rawaccessor_type,
     228             :             dest_iterator_type,
     229             :             mask_iterator_type,
     230             :             Masks::clipmask_polarity>::type                                raw_maskedaccessor_type;
     231             :         typedef typename accessor_selector::template wrap_accessor<
     232             :             raw_maskedaccessor_type >::type                                masked_accessor_type;
     233             :         typedef typename AccessorTraits<
     234             :             raw_maskedaccessor_type>::xor_accessor                         raw_maskedxor_accessor_type;
     235             :         typedef typename accessor_selector::template wrap_accessor<
     236             :             raw_maskedxor_accessor_type >::type                            masked_xoraccessor_type;
     237             : 
     238             : 
     239             : 
     240             :         // ((iter,mask),mask) special case (e.g. for clipped
     241             :         // drawMaskedColor())
     242             :         typedef AccessorTraits< raw_maskedaccessor_type >                  raw_maskedaccessor_traits;
     243             :         typedef typename raw_maskedaccessor_traits::template masked_accessor<
     244             :             mask_rawaccessor_type,
     245             :             composite_iterator_type,
     246             :             mask_iterator_type,
     247             :             Masks::clipmask_polarity>::type                                raw_maskedmask_accessor_type;
     248             : 
     249             :         typedef CompositeIterator2D<
     250             :             composite_iterator_type,
     251             :             mask_iterator_type>                                            composite_composite_mask_iterator_type;
     252             : 
     253             : 
     254             : 
     255             :         typedef ConstantColorBlendSetterAccessorAdapter<
     256             :             dest_accessor_type,
     257             :             typename alphamask_rawaccessor_type::value_type,
     258             :             Masks::alphamask_polarity>                                     colorblend_accessor_type;
     259             :         typedef AccessorTraits<colorblend_accessor_type>                   colorblend_accessor_traits;
     260             :         typedef typename colorblend_accessor_traits::template masked_accessor<
     261             :             mask_rawaccessor_type,
     262             :             dest_iterator_type,
     263             :             mask_iterator_type,
     264             :             Masks::clipmask_polarity>::type                                masked_colorblend_accessor_type;
     265             : 
     266             : 
     267             : 
     268             :         typedef ConstantColorBlendSetterAccessorAdapter<
     269             :             dest_accessor_type,
     270             :             Color,
     271             :             Masks::alphamask_polarity>                                     colorblend_generic_accessor_type;
     272             :         typedef AccessorTraits<colorblend_generic_accessor_type>           colorblend_generic_accessor_traits;
     273             :         typedef typename colorblend_generic_accessor_traits::template masked_accessor<
     274             :             mask_rawaccessor_type,
     275             :             dest_iterator_type,
     276             :             mask_iterator_type,
     277             :             Masks::clipmask_polarity>::type                                masked_colorblend_generic_accessor_type;
     278             : 
     279             : 
     280             : 
     281             :         typedef JoinImageAccessorAdapter< dest_accessor_type,
     282             :                                           mask_rawaccessor_type >          joined_image_accessor_type;
     283             :         typedef JoinImageAccessorAdapter< GenericColorImageAccessor,
     284             :                                           GenericColorImageAccessor >      joined_generic_image_accessor_type;
     285             : 
     286             : 
     287             : 
     288             :         dest_iterator_type                      maBegin;
     289             :         typename accessor_traits::color_lookup  maColorLookup;
     290             :         IBitmapDeviceDamageTrackerSharedPtr     mpDamage;
     291             :         to_uint32_functor                       maToUInt32Converter;
     292             :         dest_accessor_type                      maAccessor;
     293             :         colorblend_accessor_type                maColorBlendAccessor;
     294             :         colorblend_generic_accessor_type        maGenericColorBlendAccessor;
     295             :         raw_accessor_type                       maRawAccessor;
     296             :         xor_accessor_type                       maXorAccessor;
     297             :         raw_xor_accessor_type                   maRawXorAccessor;
     298             :         masked_accessor_type                    maMaskedAccessor;
     299             :         masked_colorblend_accessor_type         maMaskedColorBlendAccessor;
     300             :         masked_colorblend_generic_accessor_type maGenericMaskedColorBlendAccessor;
     301             :         masked_xoraccessor_type                 maMaskedXorAccessor;
     302             :         raw_maskedaccessor_type                 maRawMaskedAccessor;
     303             :         raw_maskedxor_accessor_type             maRawMaskedXorAccessor;
     304             :         raw_maskedmask_accessor_type            maRawMaskedMaskAccessor;
     305             : 
     306             : 
     307             : 
     308             : 
     309           0 :         BitmapRenderer( const basegfx::B2IBox&                     rBounds,
     310             :                         const basegfx::B2IVector&                  rBufferSize,
     311             :                         Format                                     nScanlineFormat,
     312             :                         sal_Int32                                  nScanlineStride,
     313             :                         sal_uInt8*                                 pFirstScanline,
     314             :                         dest_iterator_type                         begin,
     315             :                         raw_accessor_type                          rawAccessor,
     316             :                         dest_accessor_type                         accessor,
     317             :                         const RawMemorySharedArray&                rMem,
     318             :                         const PaletteMemorySharedVector&           rPalette,
     319             :                         const IBitmapDeviceDamageTrackerSharedPtr& rDamage ) :
     320             :             BitmapDevice( rBounds, rBufferSize, nScanlineFormat,
     321             :                           nScanlineStride, pFirstScanline, rMem, rPalette ),
     322             :             maBegin( begin ),
     323             :             maColorLookup(),
     324             :             mpDamage(rDamage),
     325             :             maToUInt32Converter(),
     326             :             maAccessor( accessor ),
     327             :             maColorBlendAccessor( accessor ),
     328             :             maGenericColorBlendAccessor( accessor ),
     329             :             maRawAccessor( rawAccessor ),
     330             :             maXorAccessor( accessor ),
     331             :             maRawXorAccessor( rawAccessor ),
     332             :             maMaskedAccessor( accessor ),
     333             :             maMaskedColorBlendAccessor( maColorBlendAccessor ),
     334             :             maGenericMaskedColorBlendAccessor( maGenericColorBlendAccessor ),
     335             :             maMaskedXorAccessor( accessor ),
     336             :             maRawMaskedAccessor( rawAccessor ),
     337             :             maRawMaskedXorAccessor( rawAccessor ),
     338           0 :             maRawMaskedMaskAccessor( rawAccessor )
     339           0 :         {}
     340             : 
     341             :     private:
     342             : 
     343           0 :         void damaged( const basegfx::B2IBox& rDamageRect ) const
     344             :         {
     345           0 :             if( mpDamage )
     346           0 :                 mpDamage->damaged( rDamageRect );
     347           0 :         }
     348             : 
     349           0 :         void damagedPointSize( const basegfx::B2IPoint& rPoint,
     350             :                                const basegfx::B2IBox&   rSize ) const
     351             :         {
     352           0 :             if( mpDamage ) {
     353           0 :                 basegfx::B2IPoint aLower( rPoint.getX() + rSize.getWidth(),
     354           0 :                                           rPoint.getY() + rSize.getHeight() );
     355           0 :                 damaged( basegfx::B2IBox( rPoint, aLower ) );
     356             :             }
     357           0 :         }
     358             : 
     359           0 :         void damagedPixel( const basegfx::B2IPoint& rDamagePoint ) const
     360             :         {
     361           0 :             if( !mpDamage )
     362           0 :                 return;
     363             : 
     364           0 :             sal_Int32 nX(rDamagePoint.getX());
     365           0 :             sal_Int32 nY(rDamagePoint.getY());
     366           0 :             if (nX < SAL_MAX_INT32)
     367           0 :                 ++nX;
     368           0 :             if (nY < SAL_MAX_INT32)
     369           0 :                 ++nY;
     370             : 
     371           0 :             basegfx::B2IPoint aEnd( nX, nY );
     372           0 :             damaged( basegfx::B2IBox( rDamagePoint, aEnd ) );
     373             :         }
     374             : 
     375           0 :         boost::shared_ptr<BitmapRenderer> getCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
     376             :         {
     377           0 :             return boost::dynamic_pointer_cast< BitmapRenderer >( bmp );
     378             :         }
     379             : 
     380           0 :         virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const SAL_OVERRIDE
     381             :         {
     382             :             // TODO(P1): dynamic_cast usually called twice for
     383             :             // compatible formats
     384           0 :             return getCompatibleBitmap(bmp).get() != NULL;
     385             :         }
     386             : 
     387           0 :         boost::shared_ptr<mask_bitmap_type> getCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const
     388             :         {
     389           0 :             boost::shared_ptr<mask_bitmap_type> pMask( boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ));
     390             : 
     391           0 :             if( !pMask )
     392           0 :                 return pMask;
     393             : 
     394           0 :             if( pMask->getSize() != getSize() )
     395           0 :                 pMask.reset();
     396             : 
     397           0 :             return pMask;
     398             :         }
     399             : 
     400           0 :         virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const SAL_OVERRIDE
     401             :         {
     402             :             // TODO(P1): dynamic_cast usually called twice for
     403             :             // compatible formats
     404           0 :             return boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ).get() != NULL;
     405             :         }
     406             : 
     407           0 :         boost::shared_ptr<alphamask_bitmap_type> getCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
     408             :         {
     409           0 :             return boost::dynamic_pointer_cast<alphamask_bitmap_type>( bmp );
     410             :         }
     411             : 
     412           0 :         virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const SAL_OVERRIDE
     413             :         {
     414             :             // TODO(P1): dynamic_cast usually called twice for
     415             :             // compatible formats
     416           0 :             return getCompatibleAlphaMask( bmp ).get() != NULL;
     417             :         }
     418             : 
     419           0 :         virtual void clear_i( Color                   fillColor,
     420             :                               const basegfx::B2IBox&  rBounds ) SAL_OVERRIDE
     421             :         {
     422           0 :             fillImage(destIterRange(maBegin,
     423             :                                     maRawAccessor,
     424           0 :                                     rBounds),
     425             :                       maColorLookup(
     426             :                           maAccessor,
     427           0 :                           fillColor) );
     428           0 :             damaged( rBounds );
     429           0 :         }
     430             : 
     431           0 :         virtual void setPixel_i( const basegfx::B2IPoint& rPt,
     432             :                                  Color                    pixelColor,
     433             :                                  DrawMode                 drawMode ) SAL_OVERRIDE
     434             :         {
     435           0 :             const DestIterator pixel( maBegin +
     436           0 :                                       vigra::Diff2D(rPt.getX(),
     437           0 :                                                     rPt.getY()) );
     438           0 :             if( drawMode == DrawMode_XOR )
     439           0 :                 maXorAccessor.set( pixelColor,
     440             :                                    pixel );
     441             :             else
     442           0 :                 maAccessor.set( pixelColor,
     443             :                                 pixel );
     444           0 :             damagedPixel(rPt);
     445           0 :         }
     446             : 
     447           0 :         virtual void setPixel_i( const basegfx::B2IPoint&     rPt,
     448             :                                  Color                        pixelColor,
     449             :                                  DrawMode                     drawMode,
     450             :                                  const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
     451             :         {
     452           0 :             boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
     453             :             OSL_ASSERT( pMask );
     454             : 
     455           0 :             const vigra::Diff2D offset(rPt.getX(),
     456           0 :                                        rPt.getY());
     457             : 
     458             :             const composite_iterator_type aIter(
     459           0 :                 maBegin + offset,
     460           0 :                 pMask->maBegin + offset );
     461             : 
     462           0 :             if( drawMode == DrawMode_XOR )
     463           0 :                 maMaskedXorAccessor.set( pixelColor,
     464             :                                          aIter );
     465             :             else
     466           0 :                 maMaskedAccessor.set( pixelColor,
     467             :                                       aIter );
     468           0 :             damagedPixel(rPt);
     469           0 :         }
     470             : 
     471           0 :         virtual Color getPixel_i(const basegfx::B2IPoint& rPt ) SAL_OVERRIDE
     472             :         {
     473           0 :             const DestIterator pixel( maBegin +
     474           0 :                                       vigra::Diff2D(rPt.getX(),
     475           0 :                                                     rPt.getY()) );
     476           0 :             return maAccessor(pixel);
     477             :         }
     478             : 
     479           0 :         virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt ) SAL_OVERRIDE
     480             :         {
     481           0 :             const DestIterator pixel( maBegin +
     482           0 :                                       vigra::Diff2D(rPt.getX(),
     483           0 :                                                     rPt.getY()) );
     484           0 :             return maToUInt32Converter(maRawAccessor(pixel));
     485             :         }
     486             : 
     487             :         template< typename Iterator, typename Col, typename RawAcc >
     488           0 :         void implRenderLine2( const basegfx::B2IPoint& rPt1,
     489             :                               const basegfx::B2IPoint& rPt2,
     490             :                               const basegfx::B2IBox&   rBounds,
     491             :                               Col                      col,
     492             :                               const Iterator&          begin,
     493             :                               const RawAcc&            rawAcc )
     494             :         {
     495           0 :             renderClippedLine( rPt1,
     496             :                                rPt2,
     497             :                                rBounds,
     498             :                                col,
     499             :                                begin,
     500           0 :                                rawAcc );
     501             :             // TODO(P2): perhaps this needs pushing up the stack a bit
     502             :             // to make more complex polygons more efficient ...
     503           0 :             damaged( basegfx::B2IBox( rPt1, rPt2 ) );
     504           0 :         }
     505             : 
     506             :         template< typename Iterator, typename Accessor, typename RawAcc >
     507           0 :         void implRenderLine( const basegfx::B2IPoint& rPt1,
     508             :                              const basegfx::B2IPoint& rPt2,
     509             :                              const basegfx::B2IBox&   rBounds,
     510             :                              Color                    col,
     511             :                              const Iterator&          begin,
     512             :                              const Accessor&          acc,
     513             :                              const RawAcc&            rawAcc )
     514             :         {
     515           0 :             implRenderLine2( rPt1,rPt2,rBounds,
     516             :                              maColorLookup( acc,
     517             :                                             col ),
     518             :                              begin,
     519           0 :                              rawAcc );
     520           0 :         }
     521             : 
     522             :         template< typename Iterator, typename RawAcc, typename XorAcc >
     523           0 :         void implDrawLine( const basegfx::B2IPoint& rPt1,
     524             :                            const basegfx::B2IPoint& rPt2,
     525             :                            const basegfx::B2IBox&   rBounds,
     526             :                            Color                    col,
     527             :                            const Iterator&          begin,
     528             :                            const RawAcc&            rawAcc,
     529             :                            const XorAcc&            xorAcc,
     530             :                            DrawMode                 drawMode )
     531             :         {
     532           0 :             if( drawMode == DrawMode_XOR )
     533           0 :                 implRenderLine( rPt1, rPt2, rBounds, col,
     534           0 :                                 begin, maAccessor, xorAcc );
     535             :             else
     536           0 :                 implRenderLine( rPt1, rPt2, rBounds, col,
     537           0 :                                 begin, maAccessor, rawAcc );
     538           0 :         }
     539             : 
     540           0 :         virtual void drawLine_i(const basegfx::B2IPoint& rPt1,
     541             :                                 const basegfx::B2IPoint& rPt2,
     542             :                                 const basegfx::B2IBox&   rBounds,
     543             :                                 Color                    lineColor,
     544             :                                 DrawMode                 drawMode ) SAL_OVERRIDE
     545             :         {
     546           0 :             implDrawLine(rPt1,rPt2,rBounds,lineColor,
     547             :                          maBegin,
     548           0 :                          maRawAccessor,maRawXorAccessor,drawMode);
     549           0 :         }
     550             : 
     551           0 :         composite_iterator_type getMaskedIter( const BitmapDeviceSharedPtr& rClip ) const
     552             :         {
     553           0 :             boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
     554             :             OSL_ASSERT( pMask );
     555             : 
     556             :             return composite_iterator_type( maBegin,
     557           0 :                                             pMask->maBegin );
     558             :         }
     559             : 
     560           0 :         virtual void drawLine_i(const basegfx::B2IPoint&     rPt1,
     561             :                                 const basegfx::B2IPoint&     rPt2,
     562             :                                 const basegfx::B2IBox&       rBounds,
     563             :                                 Color                        lineColor,
     564             :                                 DrawMode                     drawMode,
     565             :                                 const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
     566             :         {
     567           0 :             implDrawLine(rPt1,rPt2,rBounds,lineColor,
     568             :                          getMaskedIter(rClip),
     569             :                          maRawMaskedAccessor,
     570           0 :                          maRawMaskedXorAccessor,drawMode);
     571           0 :         }
     572             : 
     573             :         template< typename Iterator, typename RawAcc >
     574           0 :         void implDrawPolygon( const basegfx::B2DPolygon& rPoly,
     575             :                               const basegfx::B2IBox&     rBounds,
     576             :                               Color                      col,
     577             :                               const Iterator&            begin,
     578             :                               const RawAcc&              acc )
     579             :         {
     580           0 :             basegfx::B2DPolygon aPoly( rPoly );
     581           0 :             if( rPoly.areControlPointsUsed() )
     582           0 :                 aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
     583             : 
     584             :             const typename dest_iterator_type::value_type colorIndex( maColorLookup(
     585             :                                                                           maAccessor,
     586           0 :                                                                           col));
     587           0 :             const sal_uInt32                              nVertices( aPoly.count() );
     588           0 :             for( sal_uInt32 i=1; i<nVertices; ++i )
     589           0 :                 implRenderLine2( basegfx::fround(aPoly.getB2DPoint(i-1)),
     590             :                                  basegfx::fround(aPoly.getB2DPoint(i)),
     591             :                                  rBounds,
     592             :                                  colorIndex,
     593             :                                  begin,
     594           0 :                                  acc );
     595             : 
     596           0 :             if( nVertices > 1 && aPoly.isClosed() )
     597           0 :                 implRenderLine2( basegfx::fround(aPoly.getB2DPoint(nVertices-1)),
     598             :                                  basegfx::fround(aPoly.getB2DPoint(0)),
     599             :                                  rBounds,
     600             :                                  colorIndex,
     601             :                                  begin,
     602           0 :                                  acc );
     603           0 :         }
     604             : 
     605           0 :         virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
     606             :                                    const basegfx::B2IBox&     rBounds,
     607             :                                    Color                      lineColor,
     608             :                                    DrawMode                   drawMode ) SAL_OVERRIDE
     609             :         {
     610           0 :             if( drawMode == DrawMode_XOR )
     611           0 :                 implDrawPolygon( rPoly, rBounds, lineColor,
     612             :                                  maBegin,
     613           0 :                                  maRawXorAccessor );
     614             :             else
     615           0 :                 implDrawPolygon( rPoly, rBounds, lineColor,
     616             :                                  maBegin,
     617           0 :                                  maRawAccessor );
     618           0 :         }
     619             : 
     620           0 :         virtual void drawPolygon_i(const basegfx::B2DPolygon&   rPoly,
     621             :                                    const basegfx::B2IBox&       rBounds,
     622             :                                    Color                        lineColor,
     623             :                                    DrawMode                     drawMode,
     624             :                                    const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
     625             :         {
     626           0 :             if( drawMode == DrawMode_XOR )
     627           0 :                 implDrawPolygon( rPoly, rBounds, lineColor,
     628             :                                  getMaskedIter(rClip),
     629           0 :                                  maRawMaskedXorAccessor );
     630             :             else
     631           0 :                 implDrawPolygon( rPoly, rBounds, lineColor,
     632             :                                  getMaskedIter(rClip),
     633           0 :                                  maRawMaskedAccessor );
     634           0 :         }
     635             : 
     636             :         template< typename Iterator, typename RawAcc >
     637           0 :         void implFillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
     638             :                                   Color                          col,
     639             :                                   const Iterator&                begin,
     640             :                                   const RawAcc&                  acc,
     641             :                                   const basegfx::B2IBox&         rBounds )
     642             :         {
     643           0 :             basegfx::B2DPolyPolygon aPoly( rPoly );
     644           0 :             if( rPoly.areControlPointsUsed() )
     645           0 :                 aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
     646             : 
     647           0 :             renderClippedPolyPolygon( begin,
     648             :                                       acc,
     649             :                                       maColorLookup( maAccessor,
     650             :                                                      col),
     651             :                                       rBounds,
     652             :                                       aPoly,
     653           0 :                                       basegfx::FillRule_EVEN_ODD );
     654             : 
     655           0 :             if( mpDamage )
     656             :             {
     657           0 :                 basegfx::B2DRange const aPolyBounds( basegfx::tools::getRange(aPoly) );
     658           0 :                 damaged( basegfx::unotools::b2ISurroundingBoxFromB2DRange( aPolyBounds ) );
     659           0 :             }
     660           0 :         }
     661             : 
     662           0 :         virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
     663             :                                        Color                          fillColor,
     664             :                                        DrawMode                       drawMode,
     665             :                                        const basegfx::B2IBox&         rBounds ) SAL_OVERRIDE
     666             :         {
     667           0 :             if( drawMode == DrawMode_XOR )
     668           0 :                 implFillPolyPolygon( rPoly, fillColor,
     669             :                                      maBegin,
     670             :                                      maRawXorAccessor,
     671           0 :                                      rBounds );
     672             :             else
     673           0 :                 implFillPolyPolygon( rPoly, fillColor,
     674             :                                      maBegin,
     675             :                                      maRawAccessor,
     676           0 :                                      rBounds );
     677           0 :         }
     678             : 
     679           0 :         virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
     680             :                                        Color                          fillColor,
     681             :                                        DrawMode                       drawMode,
     682             :                                        const basegfx::B2IBox&         rBounds,
     683             :                                        const BitmapDeviceSharedPtr&   rClip ) SAL_OVERRIDE
     684             :         {
     685           0 :             if( drawMode == DrawMode_XOR )
     686           0 :                 implFillPolyPolygon( rPoly, fillColor,
     687             :                                      getMaskedIter(rClip),
     688             :                                      maRawMaskedXorAccessor,
     689           0 :                                      rBounds );
     690             :             else
     691           0 :                 implFillPolyPolygon( rPoly, fillColor,
     692             :                                      getMaskedIter(rClip),
     693             :                                      maRawMaskedAccessor,
     694           0 :                                      rBounds );
     695           0 :         }
     696             : 
     697             :         template< typename Iterator, typename RawAcc >
     698           0 :         void implDrawBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
     699             :                             const basegfx::B2IBox&       rSrcRect,
     700             :                             const basegfx::B2IBox&       rDstRect,
     701             :                             const Iterator&              begin,
     702             :                             const RawAcc&                acc)
     703             :         {
     704           0 :             boost::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
     705             :             OSL_ASSERT( pSrcBmp );
     706             : 
     707           0 :             scaleImage(
     708           0 :                 srcIterRange(pSrcBmp->maBegin,
     709           0 :                              pSrcBmp->maRawAccessor,
     710           0 :                              rSrcRect),
     711             :                 destIterRange(begin,
     712             :                               acc,
     713             :                               rDstRect),
     714           0 :                 isSharedBuffer(rSrcBitmap) );
     715           0 :             damaged( rDstRect );
     716           0 :         }
     717             : 
     718             :         template< typename Iterator, typename Acc >
     719           0 :         void implDrawBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
     720             :                                    const basegfx::B2IBox&       rSrcRect,
     721             :                                    const basegfx::B2IBox&       rDstRect,
     722             :                                    const Iterator&              begin,
     723             :                                    const Acc&                   acc)
     724             :         {
     725           0 :             GenericColorImageAccessor aSrcAcc( rSrcBitmap );
     726             : 
     727           0 :             scaleImage(
     728             :                 srcIterRange(vigra::Diff2D(),
     729             :                              aSrcAcc,
     730             :                              rSrcRect),
     731             :                 destIterRange(begin,
     732             :                               acc,
     733           0 :                               rDstRect));
     734           0 :             damaged( rDstRect );
     735           0 :         }
     736             : 
     737           0 :         void implDrawBitmapDirect(const BitmapDeviceSharedPtr& rSrcBitmap,
     738             :                                   const basegfx::B2IBox&       rSrcRect,
     739             :                                   const basegfx::B2IBox&       rDstRect)
     740             :         {
     741           0 :             sal_Int32 nSrcX = rSrcRect.getMinX();
     742           0 :             sal_Int32 nSrcY = rSrcRect.getMinY();
     743           0 :             sal_Int32 nSrcWidth = rSrcRect.getWidth();
     744           0 :             sal_Int32 nSrcHeight = rSrcRect.getHeight();
     745           0 :             sal_Int32 nDestX = rDstRect.getMinX();
     746           0 :             sal_Int32 nDestY = rDstRect.getMinY();
     747             : 
     748           0 :             char* dstBuf =  (char*)getBuffer().get();
     749           0 :             char* srcBuf =  (char*)rSrcBitmap->getBuffer().get();
     750           0 :             sal_Int32 dstStride =  getScanlineStride();
     751           0 :             sal_Int32 srcStride =  rSrcBitmap->getScanlineStride();
     752           0 :             sal_Int32 bytesPerPixel = (bitsPerPixel[getScanlineFormat()] + 7) >> 3; // round up to bytes
     753           0 :             bool dstTopDown = isTopDown();
     754           0 :             bool srcTopDown = rSrcBitmap->isTopDown();
     755             : 
     756           0 :             if (dstBuf == srcBuf && nSrcY < nDestY) // reverse copy order to avoid overlapping
     757             :             {
     758           0 :                 nSrcY = getBufferSize().getY() - nSrcY - nSrcHeight;
     759           0 :                 nDestY = getBufferSize().getY() - nDestY - nSrcHeight;
     760           0 :                 srcTopDown = !srcTopDown;
     761           0 :                 dstTopDown = !dstTopDown;
     762             :             }
     763             : 
     764           0 :             if (!dstTopDown)
     765             :             {
     766           0 :                 dstBuf += dstStride * (getBufferSize().getY() - 1);
     767           0 :                 dstStride = -dstStride;
     768             :             }
     769             : 
     770           0 :             if (!srcTopDown)
     771             :             {
     772           0 :                 srcBuf += srcStride * (rSrcBitmap->getBufferSize().getY() - 1);
     773           0 :                 srcStride = -srcStride;
     774             :             }
     775             : 
     776           0 :             char* dstline = dstBuf + dstStride * nDestY + nDestX * bytesPerPixel;
     777           0 :             char* srcline = srcBuf + srcStride * nSrcY + nSrcX * bytesPerPixel;
     778           0 :             sal_Int32 lineBytes = nSrcWidth * bytesPerPixel;
     779             : 
     780           0 :             for(; 0 < nSrcHeight; nSrcHeight--)
     781             :             {
     782           0 :                 memmove(dstline, srcline, lineBytes);
     783           0 :                 dstline += dstStride;
     784           0 :                 srcline += srcStride;
     785             :             }
     786           0 :         }
     787             : 
     788           0 :         virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
     789             :                                   const basegfx::B2IBox&       rSrcRect,
     790             :                                   const basegfx::B2IBox&       rDstRect,
     791             :                                   DrawMode                     drawMode ) SAL_OVERRIDE
     792             :         {
     793           0 :             if( isCompatibleBitmap( rSrcBitmap ) )
     794             :             {
     795           0 :                 if( drawMode == DrawMode_XOR )
     796           0 :                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
     797             :                                    maBegin,
     798           0 :                                    maRawXorAccessor);
     799           0 :                 else if (bitsPerPixel[getScanlineFormat()] >= 8
     800           0 :                          && rSrcRect.getWidth() == rDstRect.getWidth() && rSrcRect.getHeight() == rDstRect.getHeight()
     801           0 :                          && rSrcBitmap->getScanlineFormat() == getScanlineFormat())
     802           0 :                     implDrawBitmapDirect(rSrcBitmap, rSrcRect, rDstRect);
     803             :                 else
     804           0 :                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
     805             :                                    maBegin,
     806           0 :                                    maRawAccessor);
     807             :             }
     808             :             else
     809             :             {
     810           0 :                 if( drawMode == DrawMode_XOR )
     811           0 :                     implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
     812             :                                           maBegin,
     813           0 :                                           maXorAccessor);
     814             :                 else
     815           0 :                     implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
     816             :                                           maBegin,
     817           0 :                                           maAccessor);
     818             :             }
     819           0 :             damaged( rDstRect );
     820           0 :         }
     821             : 
     822           0 :         virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
     823             :                                   const basegfx::B2IBox&       rSrcRect,
     824             :                                   const basegfx::B2IBox&       rDstRect,
     825             :                                   DrawMode                     drawMode,
     826             :                                   const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
     827             :         {
     828           0 :             if( isCompatibleBitmap( rSrcBitmap ) )
     829             :             {
     830           0 :                 if( drawMode == DrawMode_XOR )
     831           0 :                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
     832             :                                    getMaskedIter(rClip),
     833           0 :                                    maRawMaskedXorAccessor);
     834             :                 else
     835           0 :                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
     836             :                                    getMaskedIter(rClip),
     837           0 :                                    maRawMaskedAccessor);
     838             :             }
     839             :             else
     840             :             {
     841           0 :                 if( drawMode == DrawMode_XOR )
     842           0 :                     implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
     843             :                                           getMaskedIter(rClip),
     844           0 :                                           maMaskedXorAccessor);
     845             :                 else
     846           0 :                     implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
     847             :                                           getMaskedIter(rClip),
     848           0 :                                           maMaskedAccessor);
     849             :             }
     850           0 :             damaged( rDstRect );
     851           0 :         }
     852             : 
     853           0 :         virtual void drawMaskedColor_i(Color                        aSrcColor,
     854             :                                        const BitmapDeviceSharedPtr& rAlphaMask,
     855             :                                        const basegfx::B2IBox&       rSrcRect,
     856             :                                        const basegfx::B2IPoint&     rDstPoint ) SAL_OVERRIDE
     857             :         {
     858           0 :             boost::shared_ptr<mask_bitmap_type>      pMask( getCompatibleClipMask(rAlphaMask) );
     859           0 :             boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
     860             : 
     861           0 :             if( pAlpha )
     862             :             {
     863           0 :                 maColorBlendAccessor.setColor( aSrcColor );
     864             : 
     865           0 :                 vigra::copyImage( srcIterRange(pAlpha->maBegin,
     866           0 :                                                pAlpha->maRawAccessor,
     867             :                                                rSrcRect),
     868             :                                   destIter(maBegin,
     869             :                                            maColorBlendAccessor,
     870           0 :                                            rDstPoint) );
     871             :             }
     872           0 :             else if( pMask )
     873             :             {
     874             :                 const composite_iterator_type aBegin(
     875           0 :                     maBegin + vigra::Diff2D(rDstPoint.getX(),
     876           0 :                                             rDstPoint.getY()),
     877           0 :                     pMask->maBegin + topLeft(rSrcRect) );
     878             : 
     879           0 :                 fillImage(aBegin,
     880           0 :                           aBegin + vigra::Diff2D(rSrcRect.getWidth(),
     881           0 :                                                  rSrcRect.getHeight()),
     882             :                           maRawMaskedAccessor,
     883             :                           maColorLookup(
     884             :                               maAccessor,
     885           0 :                               aSrcColor) );
     886             :             }
     887             :             else
     888             :             {
     889           0 :                 GenericColorImageAccessor aSrcAcc( rAlphaMask );
     890           0 :                 maGenericColorBlendAccessor.setColor( aSrcColor );
     891             : 
     892           0 :                 vigra::copyImage( srcIterRange(vigra::Diff2D(),
     893             :                                                aSrcAcc,
     894             :                                                rSrcRect),
     895             :                                   destIter(maBegin,
     896             :                                            maGenericColorBlendAccessor,
     897           0 :                                            rDstPoint) );
     898             :             }
     899           0 :             damagedPointSize( rDstPoint, rSrcRect );
     900           0 :         }
     901             : 
     902           0 :         virtual void drawMaskedColor_i(Color                        aSrcColor,
     903             :                                        const BitmapDeviceSharedPtr& rAlphaMask,
     904             :                                        const basegfx::B2IBox&       rSrcRect,
     905             :                                        const basegfx::B2IPoint&     rDstPoint,
     906             :                                        const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
     907             :         {
     908           0 :             boost::shared_ptr<mask_bitmap_type>      pMask( getCompatibleClipMask(rAlphaMask) );
     909           0 :             boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
     910             : 
     911           0 :             if( pAlpha )
     912             :             {
     913           0 :                 const composite_iterator_type aBegin( getMaskedIter(rClip) );
     914           0 :                 maMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
     915             :                     aSrcColor );
     916             : 
     917           0 :                 vigra::copyImage( srcIterRange(pAlpha->maBegin,
     918           0 :                                                pAlpha->maRawAccessor,
     919             :                                                rSrcRect),
     920             :                                   destIter(aBegin,
     921             :                                            maMaskedColorBlendAccessor,
     922           0 :                                            rDstPoint) );
     923             :             }
     924           0 :             else if( pMask )
     925             :             {
     926           0 :                 boost::shared_ptr<mask_bitmap_type> pClipMask( getCompatibleClipMask(rClip) );
     927             :                 OSL_ASSERT( pClipMask );
     928             : 
     929             :                 // setup a ((iter,mask),clipMask) composite composite
     930             :                 // iterator, to pass both masks (clip and alpha mask)
     931             :                 // to the algorithm
     932             :                 const composite_composite_mask_iterator_type aBegin(
     933             :                     composite_iterator_type(
     934           0 :                         maBegin + vigra::Diff2D(rDstPoint.getX(),
     935           0 :                                                 rDstPoint.getY()),
     936           0 :                         pMask->maBegin + topLeft(rSrcRect)),
     937           0 :                     pClipMask->maBegin + vigra::Diff2D(rDstPoint.getX(),
     938           0 :                                                        rDstPoint.getY()) );
     939             : 
     940           0 :                 fillImage(aBegin,
     941           0 :                           aBegin + vigra::Diff2D(rSrcRect.getWidth(),
     942           0 :                                                  rSrcRect.getHeight()),
     943             :                           maRawMaskedMaskAccessor,
     944             :                           maColorLookup(
     945             :                               maAccessor,
     946           0 :                               aSrcColor) );
     947             :             }
     948             :             else
     949             :             {
     950           0 :                 GenericColorImageAccessor aSrcAcc( rAlphaMask );
     951           0 :                 const composite_iterator_type aBegin( getMaskedIter(rClip) );
     952           0 :                 maGenericMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
     953             :                     aSrcColor );
     954             : 
     955           0 :                 vigra::copyImage( srcIterRange(vigra::Diff2D(),
     956             :                                                aSrcAcc,
     957             :                                                rSrcRect),
     958             :                                   destIter(aBegin,
     959             :                                            maGenericMaskedColorBlendAccessor,
     960           0 :                                            rDstPoint) );
     961             :             }
     962           0 :             damagedPointSize( rDstPoint, rSrcRect );
     963           0 :         }
     964             : 
     965             :         template< typename Iterator, typename Acc >
     966           0 :         void implDrawMaskedBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
     967             :                                   const BitmapDeviceSharedPtr& rMask,
     968             :                                   const basegfx::B2IBox&       rSrcRect,
     969             :                                   const basegfx::B2IBox&       rDstRect,
     970             :                                   const Iterator&              begin,
     971             :                                   const Acc&                   acc)
     972             :         {
     973           0 :             boost::shared_ptr<BitmapRenderer>   pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
     974           0 :             boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rMask) );
     975             :             OSL_ASSERT( pMask && pSrcBmp );
     976             : 
     977           0 :             scaleImage(
     978             :                 srcIterRange(composite_iterator_type(
     979           0 :                                  pSrcBmp->maBegin,
     980           0 :                                  pMask->maBegin),
     981             :                              joined_image_accessor_type(
     982           0 :                                  pSrcBmp->maAccessor,
     983           0 :                                  pMask->maRawAccessor),
     984             :                              rSrcRect),
     985             :                 destIterRange(begin,
     986             :                               typename masked_input_splitting_accessor<
     987             :                                        Acc,
     988             :                                        joined_image_accessor_type,
     989             :                                        Masks::clipmask_polarity,
     990             :                                        FastMask >::type(acc),
     991           0 :                               rDstRect),
     992           0 :                 isSharedBuffer(rSrcBitmap));
     993           0 :             damaged( rDstRect );
     994           0 :         }
     995             : 
     996             :         template< typename Iterator, typename Acc >
     997           0 :         void implDrawMaskedBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
     998             :                                          const BitmapDeviceSharedPtr& rMask,
     999             :                                          const basegfx::B2IBox&       rSrcRect,
    1000             :                                          const basegfx::B2IBox&       rDstRect,
    1001             :                                          const Iterator&              begin,
    1002             :                                          const Acc&                   acc)
    1003             :         {
    1004           0 :             GenericColorImageAccessor aSrcAcc( rSrcBitmap );
    1005           0 :             GenericColorImageAccessor aMaskAcc( rMask );
    1006             : 
    1007           0 :             const vigra::Diff2D aTopLeft(rSrcRect.getMinX(),
    1008           0 :                                          rSrcRect.getMinY());
    1009           0 :             const vigra::Diff2D aBottomRight(rSrcRect.getMaxX(),
    1010           0 :                                              rSrcRect.getMaxY());
    1011           0 :             scaleImage(
    1012             :                 vigra::make_triple(
    1013             :                     generic_composite_iterator_type(
    1014             :                         aTopLeft,aTopLeft),
    1015             :                     generic_composite_iterator_type(
    1016             :                         aBottomRight,aBottomRight),
    1017             :                     joined_generic_image_accessor_type(
    1018             :                         aSrcAcc,
    1019             :                         aMaskAcc)),
    1020             :                 destIterRange(begin,
    1021             :                               typename masked_input_splitting_accessor<
    1022             :                                        Acc,
    1023             :                                        joined_generic_image_accessor_type,
    1024             :                                        Masks::clipmask_polarity,
    1025             :                                        NoFastMask >::type(acc),
    1026           0 :                               rDstRect));
    1027           0 :             damaged( rDstRect );
    1028           0 :         }
    1029             : 
    1030           0 :         virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
    1031             :                                         const BitmapDeviceSharedPtr& rMask,
    1032             :                                         const basegfx::B2IBox&       rSrcRect,
    1033             :                                         const basegfx::B2IBox&       rDstRect,
    1034             :                                         DrawMode                     drawMode ) SAL_OVERRIDE
    1035             :         {
    1036           0 :             if( isCompatibleClipMask(rMask) &&
    1037           0 :                 isCompatibleBitmap(rSrcBitmap) )
    1038             :             {
    1039           0 :                 if( drawMode == DrawMode_XOR )
    1040           0 :                     implDrawMaskedBitmap(rSrcBitmap, rMask,
    1041             :                                          rSrcRect, rDstRect,
    1042             :                                          maBegin,
    1043           0 :                                          maXorAccessor);
    1044             :                 else
    1045           0 :                     implDrawMaskedBitmap(rSrcBitmap, rMask,
    1046             :                                          rSrcRect, rDstRect,
    1047             :                                          maBegin,
    1048           0 :                                          maAccessor);
    1049             :             }
    1050             :             else
    1051             :             {
    1052           0 :                 if( drawMode == DrawMode_XOR )
    1053           0 :                     implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
    1054             :                                                 rSrcRect, rDstRect,
    1055             :                                                 maBegin,
    1056           0 :                                                 maXorAccessor);
    1057             :                 else
    1058           0 :                     implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
    1059             :                                                 rSrcRect, rDstRect,
    1060             :                                                 maBegin,
    1061           0 :                                                 maAccessor);
    1062             :             }
    1063           0 :             damaged( rDstRect );
    1064           0 :         }
    1065             : 
    1066           0 :         virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
    1067             :                                         const BitmapDeviceSharedPtr& rMask,
    1068             :                                         const basegfx::B2IBox&       rSrcRect,
    1069             :                                         const basegfx::B2IBox&       rDstRect,
    1070             :                                         DrawMode                     drawMode,
    1071             :                                         const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
    1072             :         {
    1073           0 :             if( isCompatibleClipMask(rMask) &&
    1074           0 :                 isCompatibleBitmap(rSrcBitmap) )
    1075             :             {
    1076           0 :                 if( drawMode == DrawMode_XOR )
    1077           0 :                     implDrawMaskedBitmap(rSrcBitmap, rMask,
    1078             :                                          rSrcRect, rDstRect,
    1079             :                                          getMaskedIter(rClip),
    1080           0 :                                          maMaskedXorAccessor);
    1081             :                 else
    1082           0 :                     implDrawMaskedBitmap(rSrcBitmap, rMask,
    1083             :                                          rSrcRect, rDstRect,
    1084             :                                          getMaskedIter(rClip),
    1085           0 :                                          maMaskedAccessor);
    1086             :             }
    1087             :             else
    1088             :             {
    1089           0 :                 if( drawMode == DrawMode_XOR )
    1090           0 :                     implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
    1091             :                                                 rSrcRect, rDstRect,
    1092             :                                                 getMaskedIter(rClip),
    1093           0 :                                                 maMaskedXorAccessor);
    1094             :                 else
    1095           0 :                     implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
    1096             :                                                 rSrcRect, rDstRect,
    1097             :                                                 getMaskedIter(rClip),
    1098           0 :                                                 maMaskedAccessor);
    1099             :             }
    1100           0 :             damaged( rDstRect );
    1101           0 :         }
    1102             : 
    1103           0 :         IBitmapDeviceDamageTrackerSharedPtr getDamageTracker_i() const SAL_OVERRIDE
    1104             :         {
    1105           0 :             return mpDamage;
    1106             :         }
    1107           0 :         void setDamageTracker_i( const IBitmapDeviceDamageTrackerSharedPtr& rDamage ) SAL_OVERRIDE
    1108             :         {
    1109           0 :             mpDamage = rDamage;
    1110           0 :         }
    1111             :     };
    1112             : } // namespace
    1113             : 
    1114           0 : struct ImplBitmapDevice
    1115             : {
    1116             :     /** Bitmap memory plus deleter.
    1117             : 
    1118             :         Always points to the start of the mem
    1119             :      */
    1120             :     RawMemorySharedArray      mpMem;
    1121             : 
    1122             :     /// Palette memory plus deleter (might be NULL)
    1123             :     PaletteMemorySharedVector mpPalette;
    1124             : 
    1125             :     /** Bounds of the device.
    1126             : 
    1127             :         maBounds.getWidth()/getHeight() yield the true size of the
    1128             :         device (i.e. the rectangle given by maBounds covers the device
    1129             :         area under the including-the-bottommost-and-rightmost-pixels
    1130             :         fill rule)
    1131             :      */
    1132             :     basegfx::B2IBox           maBounds;
    1133             : 
    1134             :     //// Size of the actual frame buffer
    1135             :     basegfx::B2IVector        maBufferSize;
    1136             : 
    1137             :     /// Scanline format, as provided at the constructor
    1138             :     Format                    mnScanlineFormat;
    1139             : 
    1140             :     /// Scanline stride. Negative for bottom-to-top formats
    1141             :     sal_Int32                 mnScanlineStride;
    1142             : 
    1143             :     /// raw ptr to 0th scanline. used for cloning a generic renderer
    1144             :     sal_uInt8*                mpFirstScanline;
    1145             : 
    1146             :     /** (Optional) device sharing the same memory, and used for input
    1147             :         clip masks/alpha masks/bitmaps that don't match our exact
    1148             :         bitmap format.
    1149             : 
    1150             :         This is to avoid the combinatorical explosion when dealing
    1151             :         with n bitmap formats, which could be combined with n clip
    1152             :         masks, alpha masks and bitmap masks (yielding a total of n^4
    1153             :         combinations). Since each BitmapRenderer is specialized for
    1154             :         one specific combination of said formats, a lot of duplicate
    1155             :         code would be generated, most of which probably never
    1156             :         used. Therefore, only the most common combinations are
    1157             :         specialized templates, the remainder gets handled by this
    1158             :         generic renderer (via runtime polymorphism).
    1159             :      */
    1160             :     BitmapDeviceSharedPtr     mpGenericRenderer;
    1161             : };
    1162             : 
    1163             : 
    1164           0 : BitmapDevice::BitmapDevice( const basegfx::B2IBox&           rBounds,
    1165             :                             const basegfx::B2IVector&        rBufferSize,
    1166             :                             Format                           nScanlineFormat,
    1167             :                             sal_Int32                        nScanlineStride,
    1168             :                             sal_uInt8*                       pFirstScanline,
    1169             :                             const RawMemorySharedArray&      rMem,
    1170             :                             const PaletteMemorySharedVector& rPalette ) :
    1171           0 :     mpImpl( new ImplBitmapDevice )
    1172             : {
    1173           0 :     mpImpl->mpMem = rMem;
    1174           0 :     mpImpl->mpPalette = rPalette;
    1175           0 :     mpImpl->maBounds = rBounds;
    1176           0 :     mpImpl->maBufferSize = rBufferSize;
    1177           0 :     mpImpl->mnScanlineFormat = nScanlineFormat;
    1178           0 :     mpImpl->mnScanlineStride = nScanlineStride;
    1179           0 :     mpImpl->mpFirstScanline  = pFirstScanline;
    1180           0 : }
    1181             : 
    1182           0 : BitmapDevice::~BitmapDevice()
    1183             : {
    1184             :     // outline, because of internal ImplBitmapDevice
    1185             :     SAL_INFO( "basebmp.bitmapdevice", "~BitmapDevice(" << this << ")" );
    1186           0 : }
    1187             : 
    1188           0 : basegfx::B2IVector BitmapDevice::getSize() const
    1189             : {
    1190             :     return basegfx::B2IVector(
    1191           0 :         mpImpl->maBounds.getMaxX() - mpImpl->maBounds.getMinX(),
    1192           0 :         mpImpl->maBounds.getMaxY() - mpImpl->maBounds.getMinY() );
    1193             : }
    1194             : 
    1195           0 : bool BitmapDevice::isTopDown() const
    1196             : {
    1197           0 :     return mpImpl->mnScanlineStride >= 0;
    1198             : }
    1199             : 
    1200           0 : basegfx::B2IVector BitmapDevice::getBufferSize() const
    1201             : {
    1202           0 :     return mpImpl->maBufferSize;
    1203             : }
    1204             : 
    1205           0 : Format BitmapDevice::getScanlineFormat() const
    1206             : {
    1207           0 :     return mpImpl->mnScanlineFormat;
    1208             : }
    1209             : 
    1210           0 : sal_Int32 BitmapDevice::getScanlineStride() const
    1211             : {
    1212           0 :     return mpImpl->mnScanlineStride < 0 ?
    1213           0 :         -mpImpl->mnScanlineStride : mpImpl->mnScanlineStride;
    1214             : }
    1215             : 
    1216           0 : RawMemorySharedArray BitmapDevice::getBuffer() const
    1217             : {
    1218           0 :     return mpImpl->mpMem;
    1219             : }
    1220             : 
    1221           0 : IBitmapDeviceDamageTrackerSharedPtr BitmapDevice::getDamageTracker() const
    1222             : {
    1223           0 :     return getDamageTracker_i();
    1224             : }
    1225             : 
    1226           0 : void BitmapDevice::setDamageTracker( const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
    1227             : {
    1228           0 :     setDamageTracker_i(rDamage);
    1229           0 : }
    1230             : 
    1231           0 : PaletteMemorySharedVector BitmapDevice::getPalette() const
    1232             : {
    1233           0 :     return mpImpl->mpPalette;
    1234             : }
    1235             : 
    1236           0 : bool BitmapDevice::isSharedBuffer( const BitmapDeviceSharedPtr& rOther ) const
    1237             : {
    1238           0 :     return rOther.get()->getBuffer().get() == getBuffer().get();
    1239             : }
    1240             : 
    1241           0 : void BitmapDevice::clear( Color fillColor )
    1242             : {
    1243           0 :     clear_i( fillColor, mpImpl->maBounds );
    1244           0 : }
    1245             : 
    1246           0 : void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
    1247             :                              Color                    lineColor,
    1248             :                              DrawMode                 drawMode )
    1249             : {
    1250           0 :     if( mpImpl->maBounds.isInside(rPt) )
    1251           0 :         setPixel_i(rPt,lineColor,drawMode);
    1252           0 : }
    1253             : 
    1254           0 : void BitmapDevice::setPixel( const basegfx::B2IPoint&     rPt,
    1255             :                              Color                        lineColor,
    1256             :                              DrawMode                     drawMode,
    1257             :                              const BitmapDeviceSharedPtr& rClip )
    1258             : {
    1259           0 :     if( !rClip )
    1260             :     {
    1261           0 :         setPixel(rPt,lineColor,drawMode);
    1262           0 :         return;
    1263             :     }
    1264             : 
    1265           0 :     if( mpImpl->maBounds.isInside(rPt) )
    1266             :     {
    1267           0 :         if( isCompatibleClipMask( rClip ) )
    1268           0 :             setPixel_i(rPt,lineColor,drawMode,rClip);
    1269             :         else
    1270           0 :             getGenericRenderer()->setPixel( rPt, lineColor, drawMode, rClip );
    1271             :     }
    1272             : }
    1273             : 
    1274           0 : Color BitmapDevice::getPixel( const basegfx::B2IPoint& rPt )
    1275             : {
    1276           0 :     if( mpImpl->maBounds.isInside(rPt) )
    1277           0 :         return getPixel_i(rPt);
    1278             : 
    1279           0 :     return Color();
    1280             : }
    1281             : 
    1282           0 : sal_uInt32 BitmapDevice::getPixelData( const basegfx::B2IPoint& rPt )
    1283             : {
    1284           0 :     if( mpImpl->maBounds.isInside(rPt) )
    1285           0 :         return getPixelData_i(rPt);
    1286             : 
    1287           0 :     return 0;
    1288             : }
    1289             : 
    1290           0 : void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
    1291             :                              const basegfx::B2IPoint& rPt2,
    1292             :                              Color                    lineColor,
    1293             :                              DrawMode                 drawMode )
    1294             : {
    1295             :     drawLine_i( rPt1,
    1296             :                 rPt2,
    1297           0 :                 mpImpl->maBounds,
    1298             :                 lineColor,
    1299           0 :                 drawMode );
    1300           0 : }
    1301             : 
    1302           0 : void BitmapDevice::drawLine( const basegfx::B2IPoint&     rPt1,
    1303             :                              const basegfx::B2IPoint&     rPt2,
    1304             :                              Color                        lineColor,
    1305             :                              DrawMode                     drawMode,
    1306             :                              const BitmapDeviceSharedPtr& rClip )
    1307             : {
    1308           0 :     if( !rClip )
    1309             :     {
    1310           0 :         drawLine(rPt1,rPt2,lineColor,drawMode);
    1311           0 :         return;
    1312             :     }
    1313             : 
    1314           0 :     if( isCompatibleClipMask( rClip ) )
    1315             :         drawLine_i( rPt1,
    1316             :                     rPt2,
    1317           0 :                     mpImpl->maBounds,
    1318             :                     lineColor,
    1319             :                     drawMode,
    1320           0 :                     rClip );
    1321             :     else
    1322             :         getGenericRenderer()->drawLine( rPt1, rPt2, lineColor,
    1323           0 :                                         drawMode, rClip );
    1324             : }
    1325             : 
    1326           0 : void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
    1327             :                                 Color                      lineColor,
    1328             :                                 DrawMode                   drawMode )
    1329             : {
    1330           0 :     const sal_uInt32 numVertices( rPoly.count() );
    1331           0 :     if( numVertices )
    1332             :         drawPolygon_i( rPoly,
    1333           0 :                        mpImpl->maBounds,
    1334           0 :                        lineColor, drawMode );
    1335           0 : }
    1336             : 
    1337           0 : void BitmapDevice::drawPolygon( const basegfx::B2DPolygon&   rPoly,
    1338             :                                 Color                        lineColor,
    1339             :                                 DrawMode                     drawMode,
    1340             :                                 const BitmapDeviceSharedPtr& rClip )
    1341             : {
    1342           0 :     if( !rClip )
    1343             :     {
    1344           0 :         drawPolygon(rPoly,lineColor,drawMode);
    1345           0 :         return;
    1346             :     }
    1347             : 
    1348           0 :     const sal_uInt32 numVertices( rPoly.count() );
    1349           0 :     if( numVertices )
    1350             :     {
    1351           0 :         if( isCompatibleClipMask( rClip ) )
    1352             :             drawPolygon_i( rPoly,
    1353           0 :                            mpImpl->maBounds,
    1354           0 :                            lineColor, drawMode, rClip );
    1355             :         else
    1356             :             getGenericRenderer()->drawPolygon( rPoly, lineColor,
    1357           0 :                                                drawMode, rClip );
    1358             :     }
    1359             : }
    1360             : 
    1361           0 : void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
    1362             :                                     Color                          fillColor,
    1363             :                                     DrawMode                       drawMode )
    1364             : {
    1365           0 :     fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds );
    1366           0 : }
    1367             : 
    1368           0 : void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
    1369             :                                     Color                          fillColor,
    1370             :                                     DrawMode                       drawMode,
    1371             :                                     const BitmapDeviceSharedPtr&   rClip )
    1372             : {
    1373           0 :     if( !rClip )
    1374             :     {
    1375           0 :         fillPolyPolygon(rPoly,fillColor,drawMode);
    1376           0 :         return;
    1377             :     }
    1378             : 
    1379           0 :     if( isCompatibleClipMask( rClip ) )
    1380           0 :         fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds, rClip );
    1381             :     else
    1382             :         getGenericRenderer()->fillPolyPolygon( rPoly, fillColor,
    1383           0 :                                                drawMode, rClip );
    1384             : }
    1385             : 
    1386             : 
    1387             : namespace
    1388             : {
    1389           0 :     void assertImagePoint( const basegfx::B2IPoint& rPt,
    1390             :                            const basegfx::B2IBox&   rPermittedRange )
    1391             :     {
    1392             :         (void)rPt; (void)rPermittedRange;
    1393             :         OSL_ASSERT( rPermittedRange.isInside(rPt) );
    1394           0 :     }
    1395             : 
    1396           0 :     void assertImageRange( const basegfx::B2IBox& rRange,
    1397             :                            const basegfx::B2IBox& rPermittedRange )
    1398             :     {
    1399             : #if OSL_DEBUG_LEVEL > 0
    1400             :         basegfx::B2IBox aRange( rRange );
    1401             :         aRange.intersect( rPermittedRange );
    1402             : 
    1403             :         OSL_ASSERT( aRange == rRange );
    1404             : #else
    1405             :         (void)rRange; (void)rPermittedRange;
    1406             : #endif
    1407           0 :     }
    1408             : 
    1409             :     // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
    1410             :     // to basegfx, and use here!
    1411           0 :     bool clipAreaImpl( ::basegfx::B2IBox&       io_rSourceArea,
    1412             :                        ::basegfx::B2IPoint&     io_rDestPoint,
    1413             :                        const ::basegfx::B2IBox& rSourceBounds,
    1414             :                        const ::basegfx::B2IBox& rDestBounds )
    1415             :     {
    1416             :         const ::basegfx::B2IPoint aSourceTopLeft(
    1417           0 :             io_rSourceArea.getMinimum() );
    1418             : 
    1419           0 :         ::basegfx::B2IBox aLocalSourceArea( io_rSourceArea );
    1420             : 
    1421             :         // clip source area (which must be inside rSourceBounds)
    1422           0 :         aLocalSourceArea.intersect( rSourceBounds );
    1423             : 
    1424           0 :         if( aLocalSourceArea.isEmpty() )
    1425           0 :             return false;
    1426             : 
    1427             :         // calc relative new source area points (relative to orig
    1428             :         // source area)
    1429             :         const ::basegfx::B2IVector aUpperLeftOffset(
    1430           0 :             aLocalSourceArea.getMinimum()-aSourceTopLeft );
    1431             :         const ::basegfx::B2IVector aLowerRightOffset(
    1432           0 :             aLocalSourceArea.getMaximum()-aSourceTopLeft );
    1433             : 
    1434           0 :         ::basegfx::B2IBox aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
    1435           0 :                                           io_rDestPoint + aLowerRightOffset );
    1436             : 
    1437             :         // clip dest area (which must be inside rDestBounds)
    1438           0 :         aLocalDestArea.intersect( rDestBounds );
    1439             : 
    1440           0 :         if( aLocalDestArea.isEmpty() )
    1441           0 :             return false;
    1442             : 
    1443             :         // calc relative new dest area points (relative to orig
    1444             :         // source area)
    1445             :         const ::basegfx::B2IVector aDestUpperLeftOffset(
    1446           0 :             aLocalDestArea.getMinimum()-io_rDestPoint );
    1447             :         const ::basegfx::B2IVector aDestLowerRightOffset(
    1448           0 :             aLocalDestArea.getMaximum()-io_rDestPoint );
    1449             : 
    1450           0 :         io_rSourceArea = ::basegfx::B2IBox( aSourceTopLeft + aDestUpperLeftOffset,
    1451           0 :                                             aSourceTopLeft + aDestLowerRightOffset );
    1452           0 :         io_rDestPoint  = aLocalDestArea.getMinimum();
    1453             : 
    1454           0 :         return true;
    1455             :     }
    1456             : 
    1457             :     // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
    1458             :     // to basegfx, and use here!
    1459           0 :     bool clipAreaImpl( ::basegfx::B2IBox&       io_rDestArea,
    1460             :                        ::basegfx::B2IBox&       io_rSourceArea,
    1461             :                        const ::basegfx::B2IBox& rDestBounds,
    1462             :                        const ::basegfx::B2IBox& rSourceBounds )
    1463             :     {
    1464             :         // extract inherent scale
    1465           0 :         double fWidth = io_rSourceArea.getWidth();
    1466           0 :         if (fWidth == 0.0)
    1467           0 :             return false;
    1468             : 
    1469           0 :         double fHeight = io_rSourceArea.getHeight();
    1470           0 :         if (fHeight == 0.0)
    1471           0 :             return false;
    1472             : 
    1473           0 :         const double nScaleX( io_rDestArea.getWidth() / fWidth );
    1474           0 :         const double nScaleY( io_rDestArea.getHeight() / fHeight );
    1475             : 
    1476             :         // extract range origins
    1477             :         const basegfx::B2IPoint   aDestTopLeft(
    1478           0 :             io_rDestArea.getMinimum() );
    1479             :         const ::basegfx::B2IPoint aSourceTopLeft(
    1480           0 :             io_rSourceArea.getMinimum() );
    1481             : 
    1482           0 :         ::basegfx::B2IBox aLocalSourceArea( io_rSourceArea );
    1483             : 
    1484             :         // clip source area (which must be inside rSourceBounds)
    1485           0 :         aLocalSourceArea.intersect( rSourceBounds );
    1486             : 
    1487           0 :         if( aLocalSourceArea.isEmpty() )
    1488           0 :             return false;
    1489             : 
    1490             :         // calc relative new source area points (relative to orig
    1491             :         // source area)
    1492             :         const ::basegfx::B2IVector aUpperLeftOffset(
    1493           0 :             aLocalSourceArea.getMinimum()-aSourceTopLeft );
    1494             :         const ::basegfx::B2IVector aLowerRightOffset(
    1495           0 :             aLocalSourceArea.getMaximum()-aSourceTopLeft );
    1496             : 
    1497           0 :         ::basegfx::B2IBox aLocalDestArea( basegfx::fround(aDestTopLeft.getX() + nScaleX*aUpperLeftOffset.getX()),
    1498           0 :                                           basegfx::fround(aDestTopLeft.getY() + nScaleY*aUpperLeftOffset.getY()),
    1499           0 :                                           basegfx::fround(aDestTopLeft.getX() + nScaleX*aLowerRightOffset.getX()),
    1500           0 :                                           basegfx::fround(aDestTopLeft.getY() + nScaleY*aLowerRightOffset.getY()) );
    1501             : 
    1502             :         // clip dest area (which must be inside rDestBounds)
    1503           0 :         aLocalDestArea.intersect( rDestBounds );
    1504             : 
    1505           0 :         if( aLocalDestArea.isEmpty() )
    1506           0 :             return false;
    1507             : 
    1508             :         // calc relative new dest area points (relative to orig
    1509             :         // source area)
    1510             :         const ::basegfx::B2IVector aDestUpperLeftOffset(
    1511           0 :             aLocalDestArea.getMinimum()-aDestTopLeft );
    1512             :         const ::basegfx::B2IVector aDestLowerRightOffset(
    1513           0 :             aLocalDestArea.getMaximum()-aDestTopLeft );
    1514             : 
    1515           0 :         io_rSourceArea = ::basegfx::B2IBox( basegfx::fround(aSourceTopLeft.getX() + aDestUpperLeftOffset.getX()/nScaleX),
    1516           0 :                                             basegfx::fround(aSourceTopLeft.getY() + aDestUpperLeftOffset.getY()/nScaleY),
    1517           0 :                                             basegfx::fround(aSourceTopLeft.getX() + aDestLowerRightOffset.getX()/nScaleX),
    1518           0 :                                             basegfx::fround(aSourceTopLeft.getY() + aDestLowerRightOffset.getY()/nScaleY) );
    1519           0 :         io_rDestArea   = aLocalDestArea;
    1520             : 
    1521             :         // final source area clip (chopping round-offs)
    1522           0 :         io_rSourceArea.intersect( rSourceBounds );
    1523             : 
    1524           0 :         if( io_rSourceArea.isEmpty() )
    1525           0 :             return false;
    1526             : 
    1527             : 
    1528           0 :         return true;
    1529             :     }
    1530             : }
    1531             : 
    1532           0 : void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
    1533             :                                const basegfx::B2IBox&       rSrcRect,
    1534             :                                const basegfx::B2IBox&       rDstRect,
    1535             :                                DrawMode                     drawMode )
    1536             : {
    1537           0 :     const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
    1538           0 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1539           0 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1540           0 :     basegfx::B2IBox           aDestRange( rDstRect );
    1541             : 
    1542           0 :     if( clipAreaImpl( aDestRange,
    1543             :                       aSrcRange,
    1544           0 :                       mpImpl->maBounds,
    1545           0 :                       aSrcBounds ))
    1546             :     {
    1547           0 :         assertImageRange(aDestRange,mpImpl->maBounds);
    1548           0 :         assertImageRange(aSrcRange,aSrcBounds);
    1549             : 
    1550           0 :         drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode );
    1551           0 :     }
    1552           0 : }
    1553             : 
    1554           0 : void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
    1555             :                                const basegfx::B2IBox&       rSrcRect,
    1556             :                                const basegfx::B2IBox&       rDstRect,
    1557             :                                DrawMode                     drawMode,
    1558             :                                const BitmapDeviceSharedPtr& rClip )
    1559             : {
    1560           0 :     if( !rClip )
    1561             :     {
    1562           0 :         drawBitmap(rSrcBitmap,rSrcRect,rDstRect,drawMode);
    1563           0 :         return;
    1564             :     }
    1565             : 
    1566           0 :     const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
    1567           0 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1568           0 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1569           0 :     basegfx::B2IBox           aDestRange( rDstRect );
    1570             : 
    1571           0 :     if( clipAreaImpl( aDestRange,
    1572             :                       aSrcRange,
    1573           0 :                       mpImpl->maBounds,
    1574           0 :                       aSrcBounds ))
    1575             :     {
    1576           0 :         assertImageRange(aDestRange,mpImpl->maBounds);
    1577           0 :         assertImageRange(aSrcRange,aSrcBounds);
    1578             : 
    1579           0 :         if( isCompatibleClipMask( rClip ) )
    1580             :         {
    1581           0 :             drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode, rClip );
    1582             :         }
    1583             :         else
    1584             :         {
    1585             :             getGenericRenderer()->drawBitmap( rSrcBitmap, rSrcRect,
    1586           0 :                                               rDstRect, drawMode, rClip );
    1587             :         }
    1588           0 :     }
    1589             : }
    1590             : 
    1591           0 : void BitmapDevice::drawMaskedColor( Color                        aSrcColor,
    1592             :                                     const BitmapDeviceSharedPtr& rAlphaMask,
    1593             :                                     const basegfx::B2IBox&       rSrcRect,
    1594             :                                     const basegfx::B2IPoint&     rDstPoint )
    1595             : {
    1596           0 :     const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
    1597           0 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1598           0 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1599           0 :     basegfx::B2IPoint         aDestPoint( rDstPoint );
    1600             : 
    1601           0 :     if( clipAreaImpl( aSrcRange,
    1602             :                       aDestPoint,
    1603             :                       aSrcBounds,
    1604           0 :                       mpImpl->maBounds ))
    1605             :     {
    1606           0 :         assertImagePoint(aDestPoint,mpImpl->maBounds);
    1607           0 :         assertImageRange(aSrcRange,aSrcBounds);
    1608             : 
    1609           0 :         if( isSharedBuffer(rAlphaMask) )
    1610             :         {
    1611             :             // src == dest, copy rAlphaMask beforehand
    1612             : 
    1613             : 
    1614           0 :             const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
    1615           0 :                                            aSrcRange.getHeight() );
    1616             :             BitmapDeviceSharedPtr pAlphaCopy(
    1617             :                 cloneBitmapDevice( aSize,
    1618           0 :                                    shared_from_this()) );
    1619           0 :             basegfx::B2ITuple aGcc3WorkaroundTemporary;
    1620             :             const basegfx::B2IBox aAlphaRange( aGcc3WorkaroundTemporary,
    1621           0 :                                                aSize );
    1622             :             pAlphaCopy->drawBitmap(rAlphaMask,
    1623             :                                    aSrcRange,
    1624             :                                    aAlphaRange,
    1625           0 :                                    DrawMode_PAINT);
    1626           0 :             drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint );
    1627             :         }
    1628             :         else
    1629             :         {
    1630           0 :             drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint );
    1631             :         }
    1632           0 :     }
    1633           0 : }
    1634             : 
    1635           0 : void BitmapDevice::drawMaskedColor( Color                        aSrcColor,
    1636             :                                     const BitmapDeviceSharedPtr& rAlphaMask,
    1637             :                                     const basegfx::B2IBox&       rSrcRect,
    1638             :                                     const basegfx::B2IPoint&     rDstPoint,
    1639             :                                     const BitmapDeviceSharedPtr& rClip )
    1640             : {
    1641           0 :     if( !rClip )
    1642             :     {
    1643           0 :         drawMaskedColor(aSrcColor,rAlphaMask,rSrcRect,rDstPoint);
    1644           0 :         return;
    1645             :     }
    1646             : 
    1647           0 :     const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
    1648           0 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1649           0 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1650           0 :     basegfx::B2IPoint         aDestPoint( rDstPoint );
    1651             : 
    1652           0 :     if( clipAreaImpl( aSrcRange,
    1653             :                       aDestPoint,
    1654             :                       aSrcBounds,
    1655           0 :                       mpImpl->maBounds ))
    1656             :     {
    1657           0 :         assertImagePoint(aDestPoint,mpImpl->maBounds);
    1658           0 :         assertImageRange(aSrcRange,aSrcBounds);
    1659             : 
    1660           0 :         if( isCompatibleClipMask( rClip ) )
    1661             :         {
    1662           0 :             if( isSharedBuffer(rAlphaMask) )
    1663             :             {
    1664             :                 // src == dest, copy rAlphaMask beforehand
    1665             : 
    1666             : 
    1667           0 :                 const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
    1668           0 :                                                aSrcRange.getHeight() );
    1669             :                 BitmapDeviceSharedPtr pAlphaCopy(
    1670             :                     cloneBitmapDevice( aSize,
    1671           0 :                                        shared_from_this()) );
    1672           0 :                 basegfx::B2ITuple aGcc3WorkaroundTemporary;
    1673             :                 const basegfx::B2IBox aAlphaRange( aGcc3WorkaroundTemporary,
    1674           0 :                                                    aSize );
    1675             :                 pAlphaCopy->drawBitmap(rAlphaMask,
    1676             :                                        aSrcRange,
    1677             :                                        aAlphaRange,
    1678           0 :                                        DrawMode_PAINT);
    1679           0 :                 drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint, rClip );
    1680             :             }
    1681             :             else
    1682             :             {
    1683           0 :                 drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint, rClip );
    1684             :             }
    1685             :         }
    1686             :         else
    1687             :         {
    1688             :             getGenericRenderer()->drawMaskedColor( aSrcColor, rAlphaMask,
    1689           0 :                                                    rSrcRect, rDstPoint, rClip );
    1690             :         }
    1691           0 :     }
    1692             : }
    1693             : 
    1694           0 : void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
    1695             :                                      const BitmapDeviceSharedPtr& rMask,
    1696             :                                      const basegfx::B2IBox&       rSrcRect,
    1697             :                                      const basegfx::B2IBox&       rDstRect,
    1698             :                                      DrawMode                     drawMode )
    1699             : {
    1700             :     OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
    1701             : 
    1702           0 :     const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
    1703           0 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1704           0 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1705           0 :     basegfx::B2IBox           aDestRange( rDstRect );
    1706             : 
    1707           0 :     if( clipAreaImpl( aDestRange,
    1708             :                       aSrcRange,
    1709           0 :                       mpImpl->maBounds,
    1710           0 :                       aSrcBounds ))
    1711             :     {
    1712           0 :         assertImageRange(aDestRange,mpImpl->maBounds);
    1713           0 :         assertImageRange(aSrcRange,aSrcBounds);
    1714             : 
    1715           0 :         drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode );
    1716           0 :     }
    1717           0 : }
    1718             : 
    1719           0 : void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
    1720             :                                      const BitmapDeviceSharedPtr& rMask,
    1721             :                                      const basegfx::B2IBox&       rSrcRect,
    1722             :                                      const basegfx::B2IBox&       rDstRect,
    1723             :                                      DrawMode                     drawMode,
    1724             :                                      const BitmapDeviceSharedPtr& rClip )
    1725             : {
    1726           0 :     if( !rClip )
    1727             :     {
    1728           0 :         drawMaskedBitmap(rSrcBitmap,rMask,rSrcRect,rDstRect,drawMode);
    1729           0 :         return;
    1730             :     }
    1731             : 
    1732             :     OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
    1733             : 
    1734           0 :     const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
    1735           0 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1736           0 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1737           0 :     basegfx::B2IBox           aDestRange( rDstRect );
    1738             : 
    1739           0 :     if( clipAreaImpl( aDestRange,
    1740             :                       aSrcRange,
    1741           0 :                       mpImpl->maBounds,
    1742           0 :                       aSrcBounds ))
    1743             :     {
    1744           0 :         assertImageRange(aDestRange,mpImpl->maBounds);
    1745           0 :         assertImageRange(aSrcRange,aSrcBounds);
    1746             : 
    1747           0 :         if( isCompatibleClipMask( rClip ) )
    1748             :         {
    1749           0 :             drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode, rClip );
    1750             :         }
    1751             :         else
    1752             :         {
    1753             :             getGenericRenderer()->drawMaskedBitmap( rSrcBitmap, rMask, rSrcRect,
    1754           0 :                                                     rDstRect, drawMode, rClip );
    1755             :         }
    1756           0 :     }
    1757             : }
    1758             : 
    1759             : 
    1760             : 
    1761             : /** Standard clip and alpha masks
    1762             :  */
    1763             : struct StdMasks
    1764             : {
    1765             :     typedef PixelFormatTraits_GREY1_MSB   clipmask_format_traits;
    1766             :     typedef PixelFormatTraits_GREY8       alphamask_format_traits;
    1767             : 
    1768             :     /// Clipmask: 0 means opaque
    1769             :     static const bool clipmask_polarity  = false;
    1770             : 
    1771             :     /// Alpha mask: 0 means fully transparent
    1772             :     static const bool alphamask_polarity = true;
    1773             : };
    1774             : 
    1775             : 
    1776             : // Some compilers don't like the nested template wrap_accessor
    1777             : // reference in the parameter list - being slightly less type safe,
    1778             : // then.
    1779             : #ifndef BASEBMP_NO_NESTED_TEMPLATE_PARAMETER
    1780             : 
    1781             : /// Produces a specialized renderer for the given pixel format
    1782             : template< class FormatTraits, class MaskTraits >
    1783           0 : BitmapDeviceSharedPtr createRenderer(
    1784             :     const basegfx::B2IBox&                                       rBounds,
    1785             :     const basegfx::B2IVector&                                    rBufferSize,
    1786             :     Format                                                       nScanlineFormat,
    1787             :     sal_Int32                                                    nScanlineStride,
    1788             :     sal_uInt8*                                                   pFirstScanline,
    1789             :     typename FormatTraits::raw_accessor_type const&              rRawAccessor,
    1790             :     typename FormatTraits::accessor_selector::template wrap_accessor<
    1791             :           typename FormatTraits::raw_accessor_type>::type const& rAccessor,
    1792             :     boost::shared_array< sal_uInt8 >                             pMem,
    1793             :     const PaletteMemorySharedVector&                             pPal,
    1794             :     const IBitmapDeviceDamageTrackerSharedPtr&                   pDamage )
    1795             : #else
    1796             : 
    1797             : template< class FormatTraits, class MaskTraits, class Accessor >
    1798             : BitmapDeviceSharedPtr createRenderer(
    1799             :     const basegfx::B2IBox&                                       rBounds,
    1800             :     const basegfx::B2IVector&                                    rBufferSize,
    1801             :     Format                                                       nScanlineFormat,
    1802             :     sal_Int32                                                    nScanlineStride,
    1803             :     sal_uInt8*                                                   pFirstScanline,
    1804             :     typename FormatTraits::raw_accessor_type const&              rRawAccessor,
    1805             :     Accessor const&                                              rAccessor,
    1806             :     boost::shared_array< sal_uInt8 >                             pMem,
    1807             :     const PaletteMemorySharedVector&                             pPal,
    1808             :     const IBitmapDeviceDamageTrackerSharedPtr&                   pDamage )
    1809             : 
    1810             : #endif
    1811             : {
    1812             :     typedef typename FormatTraits::iterator_type                Iterator;
    1813             :     typedef BitmapRenderer< Iterator,
    1814             :                             typename FormatTraits::raw_accessor_type,
    1815             :                             typename FormatTraits::accessor_selector,
    1816             :                             MaskTraits >                        Renderer;
    1817             : 
    1818             :     return BitmapDeviceSharedPtr(
    1819             :         new Renderer( rBounds,
    1820             :                       rBufferSize,
    1821             :                       nScanlineFormat,
    1822             :                       nScanlineStride,
    1823             :                       pFirstScanline,
    1824             :                       Iterator(
    1825             :                           reinterpret_cast<typename Iterator::value_type*>(
    1826             :                               pFirstScanline),
    1827             :                           nScanlineStride),
    1828             :                       rRawAccessor,
    1829             :                       rAccessor,
    1830             :                       pMem,
    1831             :                       pPal,
    1832           0 :                       pDamage ));
    1833             : }
    1834             : 
    1835             : /// Create standard grey level palette
    1836           0 : PaletteMemorySharedVector createStandardPalette(
    1837             :     const PaletteMemorySharedVector& pPal,
    1838             :     sal_Int32                        nNumEntries )
    1839             : {
    1840           0 :     if( pPal || nNumEntries <= 0 )
    1841           0 :         return pPal;
    1842             : 
    1843             :     boost::shared_ptr< std::vector<Color> > pLocalPal(
    1844           0 :         new std::vector<Color>(nNumEntries) );
    1845             : 
    1846           0 :     const sal_Int32 nIncrement( 0x00FFFFFF/nNumEntries );
    1847           0 :     --nNumEntries;
    1848           0 :     for( sal_Int32 i=0, c=0; i<nNumEntries; ++i,c+=nIncrement )
    1849           0 :         pLocalPal->at(i) = Color(0xFF000000 | c);
    1850             : 
    1851           0 :     pLocalPal->at(nNumEntries) = Color(0xFFFFFFFF);
    1852             : 
    1853           0 :     return pLocalPal;
    1854             : }
    1855             : 
    1856             : template< class FormatTraits, class MaskTraits >
    1857           0 : BitmapDeviceSharedPtr createRenderer(
    1858             :     const basegfx::B2IBox&                     rBounds,
    1859             :     const basegfx::B2IVector&                  rBufferSize,
    1860             :     Format                                     nScanlineFormat,
    1861             :     sal_Int32                                  nScanlineStride,
    1862             :     sal_uInt8*                                 pFirstScanline,
    1863             :     boost::shared_array< sal_uInt8 >           pMem,
    1864             :     const PaletteMemorySharedVector&           pPal,
    1865             :     const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
    1866             : {
    1867             :     return createRenderer<FormatTraits,
    1868             :                           MaskTraits>(rBounds,
    1869             :                                       rBufferSize,
    1870             :                                       nScanlineFormat,
    1871             :                                       nScanlineStride,
    1872             :                                       pFirstScanline,
    1873             :                                       typename FormatTraits::raw_accessor_type(),
    1874             :                                       typename FormatTraits::accessor_selector::template
    1875             :                                       wrap_accessor<
    1876             :                                           typename FormatTraits::raw_accessor_type>::type(),
    1877             :                                       pMem,
    1878             :                                       pPal,
    1879           0 :                                       pDamage);
    1880             : }
    1881             : 
    1882             : template< class FormatTraits, class MaskTraits >
    1883           0 : BitmapDeviceSharedPtr createRenderer(
    1884             :     const basegfx::B2IBox&                     rBounds,
    1885             :     const basegfx::B2IVector&                  rBufferSize,
    1886             :     Format                                     nScanlineFormat,
    1887             :     sal_Int32                                  nScanlineStride,
    1888             :     sal_uInt8*                                 pFirstScanline,
    1889             :     boost::shared_array< sal_uInt8 >           pMem,
    1890             :     PaletteMemorySharedVector                  pPal,
    1891             :     int                                        nBitsPerPixel,
    1892             :     const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
    1893             : {
    1894           0 :     pPal = createStandardPalette(pPal,
    1895             :                                  1UL << nBitsPerPixel);
    1896             : 
    1897             :     OSL_ASSERT(pPal);
    1898             :     return createRenderer<FormatTraits,
    1899             :                           MaskTraits>(rBounds,
    1900             :                                       rBufferSize,
    1901             :                                       nScanlineFormat,
    1902             :                                       nScanlineStride,
    1903             :                                       pFirstScanline,
    1904             :                                       typename FormatTraits::raw_accessor_type(),
    1905             :                                       typename FormatTraits::accessor_selector::template
    1906             :                                           wrap_accessor<
    1907             :                                       typename FormatTraits::raw_accessor_type>::type(
    1908           0 :                                           &pPal->at(0),
    1909             :                                           pPal->size()),
    1910             :                                       pMem,
    1911             :                                       pPal,
    1912           0 :                                       pDamage);
    1913             : }
    1914             : 
    1915             : 
    1916             : // TODO(Q3): consolidate with canvas/canvastools.hxx! Best move this
    1917             : // to o3tl or sal/bithacks.hxx ...
    1918             : 
    1919             : /** Compute the next highest power of 2 of a 32-bit value
    1920             : 
    1921             :     Code devised by Sean Anderson, in good ole HAKMEM
    1922             :     tradition.
    1923             : 
    1924             :     @return 1 << (lg(x - 1) + 1)
    1925             : */
    1926           0 : inline sal_uInt32 nextPow2( sal_uInt32 x )
    1927             : {
    1928           0 :     --x;
    1929           0 :     x |= x >> 1;
    1930           0 :     x |= x >> 2;
    1931           0 :     x |= x >> 4;
    1932           0 :     x |= x >> 8;
    1933           0 :     x |= x >> 16;
    1934             : 
    1935           0 :     return ++x;
    1936             : }
    1937             : 
    1938             : 
    1939             : 
    1940             : 
    1941             : namespace
    1942             : {
    1943           0 : BitmapDeviceSharedPtr createBitmapDeviceImplInner( const basegfx::B2IVector&                  rSize,
    1944             :                                                    bool                                       bTopDown,
    1945             :                                                    Format                                     nScanlineFormat,
    1946             :                                                    boost::shared_array< sal_uInt8 >           pMem,
    1947             :                                                    PaletteMemorySharedVector                  pPal,
    1948             :                                                    const basegfx::B2IBox*                     pSubset,
    1949             :                                                    const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
    1950             : {
    1951             :     OSL_ASSERT(rSize.getX() > 0 && rSize.getY() > 0);
    1952             : 
    1953           0 :     if( nScanlineFormat <= FORMAT_NONE ||
    1954           0 :         nScanlineFormat >  FORMAT_MAX )
    1955           0 :         return BitmapDeviceSharedPtr();
    1956             : 
    1957             : 
    1958             : 
    1959           0 :     sal_Int32  nScanlineStride(0);
    1960             : 
    1961             :     // round up to full 8 bit, divide by 8
    1962           0 :     nScanlineStride = (rSize.getX()*bitsPerPixel[nScanlineFormat] + 7) >> 3;
    1963             : 
    1964             :     // rounded up to next full power-of-two number of bytes
    1965             :     const sal_uInt32 bytesPerPixel = nextPow2(
    1966           0 :         (bitsPerPixel[nScanlineFormat] + 7) >> 3);
    1967             : 
    1968             :     // now make nScanlineStride a multiple of bytesPerPixel
    1969           0 :     nScanlineStride = (nScanlineStride + bytesPerPixel - 1) / bytesPerPixel * bytesPerPixel;
    1970             : 
    1971             :     // factor in bottom-up scanline order case
    1972           0 :     nScanlineStride *= bTopDown ? 1 : -1;
    1973             : 
    1974           0 :     const sal_uInt32 nWidth(nScanlineStride < 0 ? -nScanlineStride : nScanlineStride);
    1975           0 :     const sal_uInt32 nHeight(rSize.getY());
    1976             : 
    1977           0 :     if (nHeight && nWidth && nWidth > SAL_MAX_INT32 / nHeight)
    1978             :     {
    1979             :         SAL_WARN( "basebmp", "suspicious massive alloc " << nWidth << " * " << nHeight);
    1980           0 :         return BitmapDeviceSharedPtr();
    1981             :     }
    1982             : 
    1983           0 :     const std::size_t nMemSize(nWidth * nHeight);
    1984             : 
    1985           0 :     if( !pMem )
    1986             :     {
    1987             :         pMem.reset(
    1988           0 :             reinterpret_cast<sal_uInt8*>(rtl_allocateMemory( nMemSize )),
    1989           0 :             &rtl_freeMemory );
    1990           0 :         if (pMem.get() == 0 && nMemSize != 0)
    1991           0 :             return BitmapDeviceSharedPtr();
    1992           0 :         memset(pMem.get(), 0, nMemSize);
    1993             :     }
    1994             : 
    1995             :     sal_uInt8* pFirstScanline = nScanlineStride < 0 ?
    1996           0 :         pMem.get() + nMemSize + nScanlineStride : pMem.get();
    1997             : 
    1998             :     // shrink render area to given subset, if given
    1999           0 :     basegfx::B2IBox aBounds(0,0,rSize.getX(),rSize.getY());
    2000           0 :     if( pSubset )
    2001           0 :         aBounds.intersect( *pSubset );
    2002             : 
    2003           0 :     switch( nScanlineFormat )
    2004             :     {
    2005             : 
    2006             :         // one bit formats
    2007             : 
    2008             :         case FORMAT_ONE_BIT_MSB_GREY:
    2009             :             return createRenderer<PixelFormatTraits_GREY1_MSB,StdMasks>(
    2010             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2011           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2012             : 
    2013             :         case FORMAT_ONE_BIT_LSB_GREY:
    2014             :             return createRenderer<PixelFormatTraits_GREY1_LSB,StdMasks>(
    2015             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2016           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2017             : 
    2018             :         case FORMAT_ONE_BIT_MSB_PAL:
    2019             :             return createRenderer<PixelFormatTraits_PAL1_MSB,StdMasks>(
    2020             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2021             :                 pFirstScanline, pMem, pPal,
    2022           0 :                 bitsPerPixel[nScanlineFormat], rDamage );
    2023             : 
    2024             :         case FORMAT_ONE_BIT_LSB_PAL:
    2025             :             return createRenderer<PixelFormatTraits_PAL1_LSB,StdMasks>(
    2026             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2027             :                 pFirstScanline, pMem, pPal,
    2028           0 :                 bitsPerPixel[nScanlineFormat], rDamage );
    2029             : 
    2030             : 
    2031             : 
    2032             :         // four bit formats
    2033             : 
    2034             :         case FORMAT_FOUR_BIT_MSB_GREY:
    2035             :             return createRenderer<PixelFormatTraits_GREY4_MSB,StdMasks>(
    2036             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2037           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2038             : 
    2039             :         case FORMAT_FOUR_BIT_LSB_GREY:
    2040             :             return createRenderer<PixelFormatTraits_GREY4_LSB,StdMasks>(
    2041             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2042           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2043             : 
    2044             :         case FORMAT_FOUR_BIT_MSB_PAL:
    2045             :             return createRenderer<PixelFormatTraits_PAL4_MSB,StdMasks>(
    2046             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2047             :                 pFirstScanline, pMem, pPal,
    2048           0 :                 bitsPerPixel[nScanlineFormat], rDamage );
    2049             : 
    2050             :         case FORMAT_FOUR_BIT_LSB_PAL:
    2051             :             return createRenderer<PixelFormatTraits_PAL4_LSB,StdMasks>(
    2052             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2053             :                 pFirstScanline, pMem, pPal,
    2054           0 :                 bitsPerPixel[nScanlineFormat], rDamage );
    2055             : 
    2056             : 
    2057             : 
    2058             :         // eight bit formats
    2059             : 
    2060             :         case FORMAT_EIGHT_BIT_GREY:
    2061             :             return createRenderer<PixelFormatTraits_GREY8,StdMasks>(
    2062             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2063           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2064             : 
    2065             :         case FORMAT_EIGHT_BIT_PAL:
    2066             :             return createRenderer<PixelFormatTraits_PAL8,StdMasks>(
    2067             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2068             :                 pFirstScanline, pMem, pPal,
    2069           0 :                 bitsPerPixel[nScanlineFormat], rDamage );
    2070             : 
    2071             : 
    2072             : 
    2073             :         // sixteen bit formats
    2074             : 
    2075             :         case FORMAT_SIXTEEN_BIT_LSB_TC_MASK:
    2076             :             return createRenderer<PixelFormatTraits_RGB16_565_LSB,StdMasks>(
    2077             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2078           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2079             : 
    2080             :         case FORMAT_SIXTEEN_BIT_MSB_TC_MASK:
    2081             :             return createRenderer<PixelFormatTraits_RGB16_565_MSB,StdMasks>(
    2082             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2083           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2084             : 
    2085             : 
    2086             : 
    2087             :         // twentyfour bit formats
    2088             :         case FORMAT_TWENTYFOUR_BIT_TC_MASK:
    2089             :             return createRenderer<PixelFormatTraits_BGR24,StdMasks>(
    2090             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2091           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2092             : 
    2093             : 
    2094             : 
    2095             :         // thirtytwo bit formats
    2096             : 
    2097             :         case FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA:
    2098             :             return createRenderer<PixelFormatTraits_BGRX32_8888,StdMasks>(
    2099             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2100           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2101             : 
    2102             :         case FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB:
    2103             :             return createRenderer<PixelFormatTraits_XRGB32_8888,StdMasks>(
    2104             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2105           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2106             : 
    2107             :         case FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR:
    2108             :             return createRenderer<PixelFormatTraits_XBGR32_8888,StdMasks>(
    2109             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2110           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2111             : 
    2112             :         case FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA:
    2113             :             return createRenderer<PixelFormatTraits_RGBX32_8888,StdMasks>(
    2114             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2115           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2116             : 
    2117             :         default:
    2118             :             assert(false); // this cannot happen
    2119             :     }
    2120             : 
    2121             :     // TODO(F3): other formats not yet implemented
    2122           0 :     return BitmapDeviceSharedPtr();
    2123             : }
    2124             : 
    2125           0 : BitmapDeviceSharedPtr createBitmapDeviceImpl( const basegfx::B2IVector&                  rSize,
    2126             :                                               bool                                       bTopDown,
    2127             :                                               Format                                     nScanlineFormat,
    2128             :                                               boost::shared_array< sal_uInt8 >           pMem,
    2129             :                                               PaletteMemorySharedVector                  pPal,
    2130             :                                               const basegfx::B2IBox*                     pSubset,
    2131             :                                               const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
    2132             : {
    2133           0 :     BitmapDeviceSharedPtr result( createBitmapDeviceImplInner( rSize, bTopDown, nScanlineFormat, pMem, pPal, pSubset, rDamage ) );
    2134             : 
    2135             : #ifdef SAL_LOG_INFO
    2136             :     std::ostringstream subset;
    2137             : 
    2138             :     if (pSubset)
    2139             :         subset << " subset=" << pSubset->getWidth() << "x" << pSubset->getHeight() << "@(" << pSubset->getMinX() << "," << pSubset->getMinY() << ")";
    2140             : 
    2141             :     SAL_INFO( "basebmp.bitmapdevice",
    2142             :               "createBitmapDevice: "
    2143             :               << rSize.getX() << "x" << rSize.getY()
    2144             :               << (bTopDown ? " top-down " : " bottom-up ")
    2145             :               << formatName(nScanlineFormat)
    2146             :               << subset.str()
    2147             :               << " = " << result.get() );
    2148             : #endif
    2149           0 :     return result;
    2150             : }
    2151             : } // namespace
    2152             : 
    2153             : 
    2154           0 : BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
    2155             :                                           bool                      bTopDown,
    2156             :                                           Format                    nScanlineFormat )
    2157             : {
    2158             :     return createBitmapDeviceImpl( rSize,
    2159             :                                    bTopDown,
    2160             :                                    nScanlineFormat,
    2161             :                                    boost::shared_array< sal_uInt8 >(),
    2162             :                                    PaletteMemorySharedVector(),
    2163             :                                    NULL,
    2164           0 :                                    IBitmapDeviceDamageTrackerSharedPtr() );
    2165             : }
    2166             : 
    2167           0 : BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector&        rSize,
    2168             :                                           bool                             bTopDown,
    2169             :                                           Format                           nScanlineFormat,
    2170             :                                           const PaletteMemorySharedVector& rPalette )
    2171             : {
    2172             :     return createBitmapDeviceImpl( rSize,
    2173             :                                    bTopDown,
    2174             :                                    nScanlineFormat,
    2175             :                                    boost::shared_array< sal_uInt8 >(),
    2176             :                                    rPalette,
    2177             :                                    NULL,
    2178           0 :                                    IBitmapDeviceDamageTrackerSharedPtr() );
    2179             : }
    2180             : 
    2181           0 : BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector&        rSize,
    2182             :                                           bool                             bTopDown,
    2183             :                                           Format                           nScanlineFormat,
    2184             :                                           const RawMemorySharedArray&      rMem,
    2185             :                                           const PaletteMemorySharedVector& rPalette )
    2186             : {
    2187             :     return createBitmapDeviceImpl( rSize,
    2188             :                                    bTopDown,
    2189             :                                    nScanlineFormat,
    2190             :                                    rMem,
    2191             :                                    rPalette,
    2192             :                                    NULL,
    2193           0 :                                    IBitmapDeviceDamageTrackerSharedPtr() );
    2194             : }
    2195             : 
    2196           0 : BitmapDeviceSharedPtr subsetBitmapDevice( const BitmapDeviceSharedPtr& rProto,
    2197             :                                           const basegfx::B2IBox&       rSubset )
    2198             : {
    2199             :     SAL_INFO( "basebmp.bitmapdevice", "subsetBitmapDevice: proto=" << rProto.get() );
    2200             :     return createBitmapDeviceImpl( rProto->getSize(),
    2201           0 :                                    rProto->isTopDown(),
    2202             :                                    rProto->getScanlineFormat(),
    2203             :                                    rProto->getBuffer(),
    2204             :                                    rProto->getPalette(),
    2205             :                                    &rSubset,
    2206           0 :                                    rProto->getDamageTracker() );
    2207             : }
    2208             : 
    2209           0 : BitmapDeviceSharedPtr cloneBitmapDevice( const basegfx::B2IVector&    rSize,
    2210             :                                          const BitmapDeviceSharedPtr& rProto )
    2211             : {
    2212             :     return createBitmapDeviceImpl( rSize,
    2213           0 :                                    rProto->isTopDown(),
    2214             :                                    rProto->getScanlineFormat(),
    2215             :                                    boost::shared_array< sal_uInt8 >(),
    2216             :                                    rProto->getPalette(),
    2217             :                                    NULL,
    2218           0 :                                    rProto->getDamageTracker() );
    2219             : }
    2220             : 
    2221             : 
    2222             : /// Clone our device, with GenericImageAccessor to handle all formats
    2223           0 : BitmapDeviceSharedPtr BitmapDevice::getGenericRenderer() const
    2224             : {
    2225           0 :     return mpImpl->mpGenericRenderer;
    2226             : }
    2227             : 
    2228             : } // namespace basebmp
    2229             : 
    2230             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10