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

Generated by: LCOV version 1.10