LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/basebmp/source - bitmapdevice.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 517 645 80.2 %
Date: 2013-07-09 Functions: 250 1071 23.3 %
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    10251452 : 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    20502904 :         lhs[0] ^ rhs[0],
      82    20502904 :         lhs[1] ^ rhs[1],
      83    51257260 :         lhs[2] ^ rhs[2]);
      84    10251452 :     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     1415186 :               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     1533564 :         BitmapRenderer( const basegfx::B2IBox&                     rBounds,
     286             :                         const basegfx::B2IVector&                  rBufferSize,
     287             :                         sal_Int32                                  nScanlineFormat,
     288             :                         sal_Int32                                  nScanlineStride,
     289             :                         sal_uInt8*                                 pFirstScanline,
     290             :                         dest_iterator_type                         begin,
     291             :                         raw_accessor_type                          rawAccessor,
     292             :                         dest_accessor_type                         accessor,
     293             :                         const RawMemorySharedArray&                rMem,
     294             :                         const PaletteMemorySharedVector&           rPalette,
     295             :                         const IBitmapDeviceDamageTrackerSharedPtr& rDamage ) :
     296             :             BitmapDevice( rBounds, rBufferSize, nScanlineFormat,
     297             :                           nScanlineStride, pFirstScanline, rMem, rPalette ),
     298             :             maBegin( begin ),
     299             :             maColorLookup(),
     300             :             mpDamage(rDamage),
     301             :             maToUInt32Converter(),
     302             :             maAccessor( accessor ),
     303             :             maColorBlendAccessor( accessor ),
     304             :             maGenericColorBlendAccessor( accessor ),
     305             :             maRawAccessor( rawAccessor ),
     306             :             maXorAccessor( accessor ),
     307             :             maRawXorAccessor( rawAccessor ),
     308             :             maMaskedAccessor( accessor ),
     309             :             maMaskedColorBlendAccessor( maColorBlendAccessor ),
     310             :             maGenericMaskedColorBlendAccessor( maGenericColorBlendAccessor ),
     311             :             maMaskedXorAccessor( accessor ),
     312             :             maRawMaskedAccessor( rawAccessor ),
     313             :             maRawMaskedXorAccessor( rawAccessor ),
     314     1533564 :             maRawMaskedMaskAccessor( rawAccessor )
     315     1533564 :         {}
     316             : 
     317             :     private:
     318             : 
     319     2156305 :         void damaged( const basegfx::B2IBox& rDamageRect ) const
     320             :         {
     321     2156305 :             if( mpDamage )
     322           0 :                 mpDamage->damaged( rDamageRect );
     323     2156305 :         }
     324             : 
     325      717489 :         void damagedPointSize( const basegfx::B2IPoint& rPoint,
     326             :                                const basegfx::B2IBox&   rSize ) const
     327             :         {
     328      717489 :             if( mpDamage ) {
     329           0 :                 basegfx::B2IPoint aLower( rPoint.getX() + rSize.getWidth(),
     330           0 :                                           rPoint.getY() + rSize.getHeight() );
     331           0 :                 damaged( basegfx::B2IBox( rPoint, aLower ) );
     332             :             }
     333      717489 :         }
     334             : 
     335      275276 :         void damagedPixel( const basegfx::B2IPoint& rDamagePoint ) const
     336             :         {
     337      275276 :             if( !mpDamage )
     338      550552 :                 return;
     339           0 :             basegfx::B2IPoint aEnd( rDamagePoint.getX() + 1,
     340           0 :                                     rDamagePoint.getY() + 1 );
     341           0 :             damaged( basegfx::B2IBox( rDamagePoint, aEnd ) );
     342             :         }
     343             : 
     344      691556 :         boost::shared_ptr<BitmapRenderer> getCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
     345             :         {
     346      691556 :             return boost::dynamic_pointer_cast< BitmapRenderer >( bmp );
     347             :         }
     348             : 
     349      345779 :         virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
     350             :         {
     351             :             // TODO(P1): dynamic_cast usually called twice for
     352             :             // compatible formats
     353      345779 :             return getCompatibleBitmap(bmp).get() != NULL;
     354             :         }
     355             : 
     356      835320 :         boost::shared_ptr<mask_bitmap_type> getCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const
     357             :         {
     358      835320 :             boost::shared_ptr<mask_bitmap_type> pMask( boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ));
     359             : 
     360      835320 :             if( !pMask )
     361      717486 :                 return pMask;
     362             : 
     363      117834 :             if( pMask->getSize() != getSize() )
     364           3 :                 pMask.reset();
     365             : 
     366      117834 :             return pMask;
     367             :         }
     368             : 
     369      123011 :         virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const
     370             :         {
     371             :             // TODO(P1): dynamic_cast usually called twice for
     372             :             // compatible formats
     373      123011 :             return boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ).get() != NULL;
     374             :         }
     375             : 
     376      717489 :         boost::shared_ptr<alphamask_bitmap_type> getCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
     377             :         {
     378      717489 :             return boost::dynamic_pointer_cast<alphamask_bitmap_type>( bmp );
     379             :         }
     380             : 
     381           0 :         virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
     382             :         {
     383             :             // TODO(P1): dynamic_cast usually called twice for
     384             :             // compatible formats
     385           0 :             return getCompatibleAlphaMask( bmp ).get() != NULL;
     386             :         }
     387             : 
     388       14025 :         virtual void clear_i( Color                   fillColor,
     389             :                               const basegfx::B2IBox&  rBounds )
     390             :         {
     391       14025 :             fillImage(destIterRange(maBegin,
     392             :                                     maRawAccessor,
     393       14025 :                                     rBounds),
     394             :                       maColorLookup(
     395             :                           maAccessor,
     396       42075 :                           fillColor) );
     397       14025 :             damaged( rBounds );
     398       14025 :         }
     399             : 
     400      220258 :         virtual void setPixel_i( const basegfx::B2IPoint& rPt,
     401             :                                  Color                    pixelColor,
     402             :                                  DrawMode                 drawMode )
     403             :         {
     404      440516 :             const DestIterator pixel( maBegin +
     405      220258 :                                       vigra::Diff2D(rPt.getX(),
     406      440516 :                                                     rPt.getY()) );
     407      220258 :             if( drawMode == DrawMode_XOR )
     408           0 :                 maXorAccessor.set( pixelColor,
     409             :                                    pixel );
     410             :             else
     411      220258 :                 maAccessor.set( pixelColor,
     412             :                                 pixel );
     413      220258 :             damagedPixel(rPt);
     414      220258 :         }
     415             : 
     416       55018 :         virtual void setPixel_i( const basegfx::B2IPoint&     rPt,
     417             :                                  Color                        pixelColor,
     418             :                                  DrawMode                     drawMode,
     419             :                                  const BitmapDeviceSharedPtr& rClip )
     420             :         {
     421       55018 :             boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
     422             :             OSL_ASSERT( pMask );
     423             : 
     424       55018 :             const vigra::Diff2D offset(rPt.getX(),
     425      110036 :                                        rPt.getY());
     426             : 
     427             :             const composite_iterator_type aIter(
     428       55018 :                 maBegin + offset,
     429      110036 :                 pMask->maBegin + offset );
     430             : 
     431       55018 :             if( drawMode == DrawMode_XOR )
     432           0 :                 maMaskedXorAccessor.set( pixelColor,
     433             :                                          aIter );
     434             :             else
     435       55018 :                 maMaskedAccessor.set( pixelColor,
     436             :                                       aIter );
     437       55018 :             damagedPixel(rPt);
     438       55018 :         }
     439             : 
     440    82327657 :         virtual Color getPixel_i(const basegfx::B2IPoint& rPt )
     441             :         {
     442   164655314 :             const DestIterator pixel( maBegin +
     443    82327657 :                                       vigra::Diff2D(rPt.getX(),
     444   164655314 :                                                     rPt.getY()) );
     445    82327657 :             return maAccessor(pixel);
     446             :         }
     447             : 
     448           4 :         virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt )
     449             :         {
     450           8 :             const DestIterator pixel( maBegin +
     451           4 :                                       vigra::Diff2D(rPt.getX(),
     452           8 :                                                     rPt.getY()) );
     453           4 :             return maToUInt32Converter(maRawAccessor(pixel));
     454             :         }
     455             : 
     456             :         template< typename Iterator, typename Col, typename RawAcc >
     457     1440362 :         void implRenderLine2( const basegfx::B2IPoint& rPt1,
     458             :                               const basegfx::B2IPoint& rPt2,
     459             :                               const basegfx::B2IBox&   rBounds,
     460             :                               Col                      col,
     461             :                               const Iterator&          begin,
     462             :                               const RawAcc&            rawAcc )
     463             :         {
     464     1440362 :             renderClippedLine( rPt1,
     465             :                                rPt2,
     466             :                                rBounds,
     467             :                                col,
     468             :                                begin,
     469     2880724 :                                rawAcc );
     470             :             // TODO(P2): perhaps this needs pushing up the stack a bit
     471             :             // to make more complex polygons more efficient ...
     472     1440362 :             damaged( basegfx::B2IBox( rPt1, rPt2 ) );
     473     1440362 :         }
     474             : 
     475             :         template< typename Iterator, typename Accessor, typename RawAcc >
     476      572590 :         void implRenderLine( const basegfx::B2IPoint& rPt1,
     477             :                              const basegfx::B2IPoint& rPt2,
     478             :                              const basegfx::B2IBox&   rBounds,
     479             :                              Color                    col,
     480             :                              const Iterator&          begin,
     481             :                              const Accessor&          acc,
     482             :                              const RawAcc&            rawAcc )
     483             :         {
     484      572590 :             implRenderLine2( rPt1,rPt2,rBounds,
     485             :                              maColorLookup( acc,
     486             :                                             col ),
     487             :                              begin,
     488     1145150 :                              rawAcc );
     489      572590 :         }
     490             : 
     491             :         template< typename Iterator, typename RawAcc, typename XorAcc >
     492      572590 :         void implDrawLine( const basegfx::B2IPoint& rPt1,
     493             :                            const basegfx::B2IPoint& rPt2,
     494             :                            const basegfx::B2IBox&   rBounds,
     495             :                            Color                    col,
     496             :                            const Iterator&          begin,
     497             :                            const RawAcc&            rawAcc,
     498             :                            const XorAcc&            xorAcc,
     499             :                            DrawMode                 drawMode )
     500             :         {
     501      572590 :             if( drawMode == DrawMode_XOR )
     502           8 :                 implRenderLine( rPt1, rPt2, rBounds, col,
     503           8 :                                 begin, maAccessor, xorAcc );
     504             :             else
     505      572582 :                 implRenderLine( rPt1, rPt2, rBounds, col,
     506      572582 :                                 begin, maAccessor, rawAcc );
     507      572590 :         }
     508             : 
     509      565369 :         virtual void drawLine_i(const basegfx::B2IPoint& rPt1,
     510             :                                 const basegfx::B2IPoint& rPt2,
     511             :                                 const basegfx::B2IBox&   rBounds,
     512             :                                 Color                    lineColor,
     513             :                                 DrawMode                 drawMode )
     514             :         {
     515      565369 :             implDrawLine(rPt1,rPt2,rBounds,lineColor,
     516             :                          maBegin,
     517      565369 :                          maRawAccessor,maRawXorAccessor,drawMode);
     518      565369 :         }
     519             : 
     520       62809 :         composite_iterator_type getMaskedIter( const BitmapDeviceSharedPtr& rClip ) const
     521             :         {
     522       62809 :             boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
     523             :             OSL_ASSERT( pMask );
     524             : 
     525             :             return composite_iterator_type( maBegin,
     526       62809 :                                             pMask->maBegin );
     527             :         }
     528             : 
     529        7221 :         virtual void drawLine_i(const basegfx::B2IPoint&     rPt1,
     530             :                                 const basegfx::B2IPoint&     rPt2,
     531             :                                 const basegfx::B2IBox&       rBounds,
     532             :                                 Color                        lineColor,
     533             :                                 DrawMode                     drawMode,
     534             :                                 const BitmapDeviceSharedPtr& rClip )
     535             :         {
     536        7221 :             implDrawLine(rPt1,rPt2,rBounds,lineColor,
     537             :                          getMaskedIter(rClip),
     538             :                          maRawMaskedAccessor,
     539       14442 :                          maRawMaskedXorAccessor,drawMode);
     540        7221 :         }
     541             : 
     542             :         template< typename Iterator, typename RawAcc >
     543      165110 :         void implDrawPolygon( const basegfx::B2DPolygon& rPoly,
     544             :                               const basegfx::B2IBox&     rBounds,
     545             :                               Color                      col,
     546             :                               const Iterator&            begin,
     547             :                               const RawAcc&              acc )
     548             :         {
     549      165110 :             basegfx::B2DPolygon aPoly( rPoly );
     550      165110 :             if( rPoly.areControlPointsUsed() )
     551           0 :                 aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
     552             : 
     553             :             const typename dest_iterator_type::value_type colorIndex( maColorLookup(
     554             :                                                                           maAccessor,
     555      165110 :                                                                           col));
     556      165110 :             const sal_uInt32                              nVertices( aPoly.count() );
     557     1026692 :             for( sal_uInt32 i=1; i<nVertices; ++i )
     558      861582 :                 implRenderLine2( basegfx::fround(aPoly.getB2DPoint(i-1)),
     559             :                                  basegfx::fround(aPoly.getB2DPoint(i)),
     560             :                                  rBounds,
     561             :                                  colorIndex,
     562             :                                  begin,
     563     1723164 :                                  acc );
     564             : 
     565      165110 :             if( nVertices > 1 && aPoly.isClosed() )
     566        6190 :                 implRenderLine2( basegfx::fround(aPoly.getB2DPoint(nVertices-1)),
     567             :                                  basegfx::fround(aPoly.getB2DPoint(0)),
     568             :                                  rBounds,
     569             :                                  colorIndex,
     570             :                                  begin,
     571       12380 :                                  acc );
     572      165110 :         }
     573             : 
     574      163834 :         virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
     575             :                                    const basegfx::B2IBox&     rBounds,
     576             :                                    Color                      lineColor,
     577             :                                    DrawMode                   drawMode )
     578             :         {
     579      163834 :             if( drawMode == DrawMode_XOR )
     580           0 :                 implDrawPolygon( rPoly, rBounds, lineColor,
     581             :                                  maBegin,
     582           0 :                                  maRawXorAccessor );
     583             :             else
     584      163834 :                 implDrawPolygon( rPoly, rBounds, lineColor,
     585             :                                  maBegin,
     586      163834 :                                  maRawAccessor );
     587      163834 :         }
     588             : 
     589        1276 :         virtual void drawPolygon_i(const basegfx::B2DPolygon&   rPoly,
     590             :                                    const basegfx::B2IBox&       rBounds,
     591             :                                    Color                        lineColor,
     592             :                                    DrawMode                     drawMode,
     593             :                                    const BitmapDeviceSharedPtr& rClip )
     594             :         {
     595        1276 :             if( drawMode == DrawMode_XOR )
     596           0 :                 implDrawPolygon( rPoly, rBounds, lineColor,
     597             :                                  getMaskedIter(rClip),
     598           0 :                                  maRawMaskedXorAccessor );
     599             :             else
     600        1276 :                 implDrawPolygon( rPoly, rBounds, lineColor,
     601             :                                  getMaskedIter(rClip),
     602        2552 :                                  maRawMaskedAccessor );
     603        1276 :         }
     604             : 
     605             :         template< typename Iterator, typename RawAcc >
     606     2155923 :         void implFillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
     607             :                                   Color                          col,
     608             :                                   const Iterator&                begin,
     609             :                                   const RawAcc&                  acc,
     610             :                                   const basegfx::B2IBox&         rBounds )
     611             :         {
     612     2155923 :             basegfx::B2DPolyPolygon aPoly( rPoly );
     613     2155923 :             if( rPoly.areControlPointsUsed() )
     614           0 :                 aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
     615             : 
     616     2155923 :             renderClippedPolyPolygon( begin,
     617             :                                       acc,
     618             :                                       maColorLookup( maAccessor,
     619             :                                                      col),
     620             :                                       rBounds,
     621             :                                       aPoly,
     622     4232555 :                                       basegfx::FillRule_EVEN_ODD );
     623             : 
     624     2155923 :             if( mpDamage )
     625             :             {
     626           0 :                 basegfx::B2DRange const aPolyBounds( basegfx::tools::getRange(aPoly) );
     627           0 :                 damaged( basegfx::unotools::b2ISurroundingBoxFromB2DRange( aPolyBounds ) );
     628     2155923 :             }
     629     2155923 :         }
     630             : 
     631     2104082 :         virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
     632             :                                        Color                          fillColor,
     633             :                                        DrawMode                       drawMode,
     634             :                                        const basegfx::B2IBox&         rBounds )
     635             :         {
     636     2104082 :             if( drawMode == DrawMode_XOR )
     637       40759 :                 implFillPolyPolygon( rPoly, fillColor,
     638             :                                      maBegin,
     639             :                                      maRawXorAccessor,
     640       40759 :                                      rBounds );
     641             :             else
     642     2063323 :                 implFillPolyPolygon( rPoly, fillColor,
     643             :                                      maBegin,
     644             :                                      maRawAccessor,
     645     2063323 :                                      rBounds );
     646     2104082 :         }
     647             : 
     648       51841 :         virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
     649             :                                        Color                          fillColor,
     650             :                                        DrawMode                       drawMode,
     651             :                                        const basegfx::B2IBox&         rBounds,
     652             :                                        const BitmapDeviceSharedPtr&   rClip )
     653             :         {
     654       51841 :             if( drawMode == DrawMode_XOR )
     655         102 :                 implFillPolyPolygon( rPoly, fillColor,
     656             :                                      getMaskedIter(rClip),
     657             :                                      maRawMaskedXorAccessor,
     658         204 :                                      rBounds );
     659             :             else
     660       51739 :                 implFillPolyPolygon( rPoly, fillColor,
     661             :                                      getMaskedIter(rClip),
     662             :                                      maRawMaskedAccessor,
     663      103478 :                                      rBounds );
     664       51841 :         }
     665             : 
     666             :         template< typename Iterator, typename RawAcc >
     667      345773 :         void implDrawBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
     668             :                             const basegfx::B2IBox&       rSrcRect,
     669             :                             const basegfx::B2IBox&       rDstRect,
     670             :                             const Iterator&              begin,
     671             :                             const RawAcc&                acc)
     672             :         {
     673      345773 :             boost::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
     674             :             OSL_ASSERT( pSrcBmp );
     675             : 
     676      345773 :             scaleImage(
     677      345773 :                 srcIterRange(pSrcBmp->maBegin,
     678      345773 :                              pSrcBmp->maRawAccessor,
     679      691546 :                              rSrcRect),
     680             :                 destIterRange(begin,
     681             :                               acc,
     682             :                               rDstRect),
     683     1037319 :                 isSharedBuffer(rSrcBitmap) );
     684      345773 :             damaged( rDstRect );
     685      345773 :         }
     686             : 
     687             :         template< typename Iterator, typename Acc >
     688           2 :         void implDrawBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
     689             :                                    const basegfx::B2IBox&       rSrcRect,
     690             :                                    const basegfx::B2IBox&       rDstRect,
     691             :                                    const Iterator&              begin,
     692             :                                    const Acc&                   acc)
     693             :         {
     694           2 :             GenericColorImageAccessor aSrcAcc( rSrcBitmap );
     695             : 
     696           2 :             scaleImage(
     697             :                 srcIterRange(vigra::Diff2D(),
     698             :                              aSrcAcc,
     699             :                              rSrcRect),
     700             :                 destIterRange(begin,
     701             :                               acc,
     702           4 :                               rDstRect));
     703           2 :             damaged( rDstRect );
     704           2 :         }
     705             : 
     706      344413 :         virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
     707             :                                   const basegfx::B2IBox&       rSrcRect,
     708             :                                   const basegfx::B2IBox&       rDstRect,
     709             :                                   DrawMode                     drawMode )
     710             :         {
     711      344413 :             if( isCompatibleBitmap( rSrcBitmap ) )
     712             :             {
     713      344411 :                 if( drawMode == DrawMode_XOR )
     714           0 :                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
     715             :                                    maBegin,
     716           0 :                                    maRawXorAccessor);
     717             :                 else
     718      344411 :                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
     719             :                                    maBegin,
     720      344411 :                                    maRawAccessor);
     721             :             }
     722             :             else
     723             :             {
     724           2 :                 if( drawMode == DrawMode_XOR )
     725           0 :                     implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
     726             :                                           maBegin,
     727           0 :                                           maXorAccessor);
     728             :                 else
     729           2 :                     implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
     730             :                                           maBegin,
     731           2 :                                           maAccessor);
     732             :             }
     733      344413 :             damaged( rDstRect );
     734      344413 :         }
     735             : 
     736        1362 :         virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
     737             :                                   const basegfx::B2IBox&       rSrcRect,
     738             :                                   const basegfx::B2IBox&       rDstRect,
     739             :                                   DrawMode                     drawMode,
     740             :                                   const BitmapDeviceSharedPtr& rClip )
     741             :         {
     742        1362 :             if( isCompatibleBitmap( rSrcBitmap ) )
     743             :             {
     744        1362 :                 if( drawMode == DrawMode_XOR )
     745           0 :                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
     746             :                                    getMaskedIter(rClip),
     747           0 :                                    maRawMaskedXorAccessor);
     748             :                 else
     749        1362 :                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
     750             :                                    getMaskedIter(rClip),
     751        2724 :                                    maRawMaskedAccessor);
     752             :             }
     753             :             else
     754             :             {
     755           0 :                 if( drawMode == DrawMode_XOR )
     756           0 :                     implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
     757             :                                           getMaskedIter(rClip),
     758           0 :                                           maMaskedXorAccessor);
     759             :                 else
     760           0 :                     implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
     761             :                                           getMaskedIter(rClip),
     762           0 :                                           maMaskedAccessor);
     763             :             }
     764        1362 :             damaged( rDstRect );
     765        1362 :         }
     766             : 
     767      716380 :         virtual void drawMaskedColor_i(Color                        aSrcColor,
     768             :                                        const BitmapDeviceSharedPtr& rAlphaMask,
     769             :                                        const basegfx::B2IBox&       rSrcRect,
     770             :                                        const basegfx::B2IPoint&     rDstPoint )
     771             :         {
     772      716380 :             boost::shared_ptr<mask_bitmap_type>      pMask( getCompatibleClipMask(rAlphaMask) );
     773     1432760 :             boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
     774             : 
     775      716380 :             if( pAlpha )
     776             :             {
     777      716377 :                 maColorBlendAccessor.setColor( aSrcColor );
     778             : 
     779     1432754 :                 vigra::copyImage( srcIterRange(pAlpha->maBegin,
     780      716377 :                                                pAlpha->maRawAccessor,
     781             :                                                rSrcRect),
     782             :                                   destIter(maBegin,
     783             :                                            maColorBlendAccessor,
     784     2149131 :                                            rDstPoint) );
     785             :             }
     786           3 :             else if( pMask )
     787             :             {
     788             :                 const composite_iterator_type aBegin(
     789           0 :                     maBegin + vigra::Diff2D(rDstPoint.getX(),
     790           0 :                                             rDstPoint.getY()),
     791           0 :                     pMask->maBegin + topLeft(rSrcRect) );
     792             : 
     793           0 :                 fillImage(aBegin,
     794           0 :                           aBegin + vigra::Diff2D(rSrcRect.getWidth(),
     795           0 :                                                  rSrcRect.getHeight()),
     796             :                           maRawMaskedAccessor,
     797             :                           maColorLookup(
     798             :                               maAccessor,
     799           0 :                               aSrcColor) );
     800             :             }
     801             :             else
     802             :             {
     803           3 :                 GenericColorImageAccessor aSrcAcc( rAlphaMask );
     804           3 :                 maGenericColorBlendAccessor.setColor( aSrcColor );
     805             : 
     806           3 :                 vigra::copyImage( srcIterRange(vigra::Diff2D(),
     807             :                                                aSrcAcc,
     808             :                                                rSrcRect),
     809             :                                   destIter(maBegin,
     810             :                                            maGenericColorBlendAccessor,
     811           6 :                                            rDstPoint) );
     812             :             }
     813     1432760 :             damagedPointSize( rDstPoint, rSrcRect );
     814      716380 :         }
     815             : 
     816        1109 :         virtual void drawMaskedColor_i(Color                        aSrcColor,
     817             :                                        const BitmapDeviceSharedPtr& rAlphaMask,
     818             :                                        const basegfx::B2IBox&       rSrcRect,
     819             :                                        const basegfx::B2IPoint&     rDstPoint,
     820             :                                        const BitmapDeviceSharedPtr& rClip )
     821             :         {
     822        1109 :             boost::shared_ptr<mask_bitmap_type>      pMask( getCompatibleClipMask(rAlphaMask) );
     823        2218 :             boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
     824             : 
     825        1109 :             if( pAlpha )
     826             :             {
     827        1109 :                 const composite_iterator_type aBegin( getMaskedIter(rClip) );
     828        1109 :                 maMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
     829             :                     aSrcColor );
     830             : 
     831        2218 :                 vigra::copyImage( srcIterRange(pAlpha->maBegin,
     832        1109 :                                                pAlpha->maRawAccessor,
     833             :                                                rSrcRect),
     834             :                                   destIter(aBegin,
     835             :                                            maMaskedColorBlendAccessor,
     836        4436 :                                            rDstPoint) );
     837             :             }
     838           0 :             else if( pMask )
     839             :             {
     840           0 :                 boost::shared_ptr<mask_bitmap_type> pClipMask( getCompatibleClipMask(rClip) );
     841             :                 OSL_ASSERT( pClipMask );
     842             : 
     843             :                 // setup a ((iter,mask),clipMask) composite composite
     844             :                 // iterator, to pass both masks (clip and alpha mask)
     845             :                 // to the algorithm
     846             :                 const composite_composite_mask_iterator_type aBegin(
     847             :                     composite_iterator_type(
     848           0 :                         maBegin + vigra::Diff2D(rDstPoint.getX(),
     849           0 :                                                 rDstPoint.getY()),
     850           0 :                         pMask->maBegin + topLeft(rSrcRect)),
     851           0 :                     pClipMask->maBegin + vigra::Diff2D(rDstPoint.getX(),
     852           0 :                                                        rDstPoint.getY()) );
     853             : 
     854           0 :                 fillImage(aBegin,
     855           0 :                           aBegin + vigra::Diff2D(rSrcRect.getWidth(),
     856           0 :                                                  rSrcRect.getHeight()),
     857             :                           maRawMaskedMaskAccessor,
     858             :                           maColorLookup(
     859             :                               maAccessor,
     860           0 :                               aSrcColor) );
     861             :             }
     862             :             else
     863             :             {
     864           0 :                 GenericColorImageAccessor aSrcAcc( rAlphaMask );
     865           0 :                 const composite_iterator_type aBegin( getMaskedIter(rClip) );
     866           0 :                 maGenericMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
     867             :                     aSrcColor );
     868             : 
     869           0 :                 vigra::copyImage( srcIterRange(vigra::Diff2D(),
     870             :                                                aSrcAcc,
     871             :                                                rSrcRect),
     872             :                                   destIter(aBegin,
     873             :                                            maGenericMaskedColorBlendAccessor,
     874           0 :                                            rDstPoint) );
     875             :             }
     876        2218 :             damagedPointSize( rDstPoint, rSrcRect );
     877        1109 :         }
     878             : 
     879             :         template< typename Iterator, typename Acc >
     880           4 :         void implDrawMaskedBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
     881             :                                   const BitmapDeviceSharedPtr& rMask,
     882             :                                   const basegfx::B2IBox&       rSrcRect,
     883             :                                   const basegfx::B2IBox&       rDstRect,
     884             :                                   const Iterator&              begin,
     885             :                                   const Acc&                   acc)
     886             :         {
     887           4 :             boost::shared_ptr<BitmapRenderer>   pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
     888           8 :             boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rMask) );
     889             :             OSL_ASSERT( pMask && pSrcBmp );
     890             : 
     891           4 :             scaleImage(
     892             :                 srcIterRange(composite_iterator_type(
     893           4 :                                  pSrcBmp->maBegin,
     894           4 :                                  pMask->maBegin),
     895             :                              joined_image_accessor_type(
     896           4 :                                  pSrcBmp->maAccessor,
     897           4 :                                  pMask->maRawAccessor),
     898             :                              rSrcRect),
     899             :                 destIterRange(begin,
     900             :                               typename masked_input_splitting_accessor<
     901             :                                        Acc,
     902             :                                        joined_image_accessor_type,
     903             :                                        Masks::clipmask_polarity,
     904             :                                        FastMask >::type(acc),
     905           8 :                               rDstRect),
     906          24 :                 isSharedBuffer(rSrcBitmap));
     907           8 :             damaged( rDstRect );
     908           4 :         }
     909             : 
     910             :         template< typename Iterator, typename Acc >
     911        5180 :         void implDrawMaskedBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
     912             :                                          const BitmapDeviceSharedPtr& rMask,
     913             :                                          const basegfx::B2IBox&       rSrcRect,
     914             :                                          const basegfx::B2IBox&       rDstRect,
     915             :                                          const Iterator&              begin,
     916             :                                          const Acc&                   acc)
     917             :         {
     918        5180 :             GenericColorImageAccessor aSrcAcc( rSrcBitmap );
     919       10360 :             GenericColorImageAccessor aMaskAcc( rMask );
     920             : 
     921        5180 :             const vigra::Diff2D aTopLeft(rSrcRect.getMinX(),
     922       10360 :                                          rSrcRect.getMinY());
     923        5180 :             const vigra::Diff2D aBottomRight(rSrcRect.getMaxX(),
     924       10360 :                                              rSrcRect.getMaxY());
     925        5180 :             scaleImage(
     926             :                 vigra::make_triple(
     927             :                     generic_composite_iterator_type(
     928             :                         aTopLeft,aTopLeft),
     929             :                     generic_composite_iterator_type(
     930             :                         aBottomRight,aBottomRight),
     931             :                     joined_generic_image_accessor_type(
     932             :                         aSrcAcc,
     933             :                         aMaskAcc)),
     934             :                 destIterRange(begin,
     935             :                               typename masked_input_splitting_accessor<
     936             :                                        Acc,
     937             :                                        joined_generic_image_accessor_type,
     938             :                                        Masks::clipmask_polarity,
     939             :                                        NoFastMask >::type(acc),
     940       10360 :                               rDstRect));
     941       10360 :             damaged( rDstRect );
     942        5180 :         }
     943             : 
     944        5184 :         virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
     945             :                                         const BitmapDeviceSharedPtr& rMask,
     946             :                                         const basegfx::B2IBox&       rSrcRect,
     947             :                                         const basegfx::B2IBox&       rDstRect,
     948             :                                         DrawMode                     drawMode )
     949             :         {
     950        5188 :             if( isCompatibleClipMask(rMask) &&
     951           4 :                 isCompatibleBitmap(rSrcBitmap) )
     952             :             {
     953           4 :                 if( drawMode == DrawMode_XOR )
     954           0 :                     implDrawMaskedBitmap(rSrcBitmap, rMask,
     955             :                                          rSrcRect, rDstRect,
     956             :                                          maBegin,
     957           0 :                                          maXorAccessor);
     958             :                 else
     959           4 :                     implDrawMaskedBitmap(rSrcBitmap, rMask,
     960             :                                          rSrcRect, rDstRect,
     961             :                                          maBegin,
     962           4 :                                          maAccessor);
     963             :             }
     964             :             else
     965             :             {
     966        5180 :                 if( drawMode == DrawMode_XOR )
     967           0 :                     implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
     968             :                                                 rSrcRect, rDstRect,
     969             :                                                 maBegin,
     970           0 :                                                 maXorAccessor);
     971             :                 else
     972        5180 :                     implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
     973             :                                                 rSrcRect, rDstRect,
     974             :                                                 maBegin,
     975        5180 :                                                 maAccessor);
     976             :             }
     977        5184 :             damaged( rDstRect );
     978        5184 :         }
     979             : 
     980           0 :         virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
     981             :                                         const BitmapDeviceSharedPtr& rMask,
     982             :                                         const basegfx::B2IBox&       rSrcRect,
     983             :                                         const basegfx::B2IBox&       rDstRect,
     984             :                                         DrawMode                     drawMode,
     985             :                                         const BitmapDeviceSharedPtr& rClip )
     986             :         {
     987           0 :             if( isCompatibleClipMask(rMask) &&
     988           0 :                 isCompatibleBitmap(rSrcBitmap) )
     989             :             {
     990           0 :                 if( drawMode == DrawMode_XOR )
     991           0 :                     implDrawMaskedBitmap(rSrcBitmap, rMask,
     992             :                                          rSrcRect, rDstRect,
     993             :                                          getMaskedIter(rClip),
     994           0 :                                          maMaskedXorAccessor);
     995             :                 else
     996           0 :                     implDrawMaskedBitmap(rSrcBitmap, rMask,
     997             :                                          rSrcRect, rDstRect,
     998             :                                          getMaskedIter(rClip),
     999           0 :                                          maMaskedAccessor);
    1000             :             }
    1001             :             else
    1002             :             {
    1003           0 :                 if( drawMode == DrawMode_XOR )
    1004           0 :                     implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
    1005             :                                                 rSrcRect, rDstRect,
    1006             :                                                 getMaskedIter(rClip),
    1007           0 :                                                 maMaskedXorAccessor);
    1008             :                 else
    1009           0 :                     implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
    1010             :                                                 rSrcRect, rDstRect,
    1011             :                                                 getMaskedIter(rClip),
    1012           0 :                                                 maMaskedAccessor);
    1013             :             }
    1014           0 :             damaged( rDstRect );
    1015           0 :         }
    1016             : 
    1017      450488 :         IBitmapDeviceDamageTrackerSharedPtr getDamageTracker_i() const
    1018             :         {
    1019      450488 :             return mpDamage;
    1020             :         }
    1021           0 :         void setDamageTracker_i( const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
    1022             :         {
    1023           0 :             mpDamage = rDamage;
    1024           0 :         }
    1025             :     };
    1026             : } // namespace
    1027             : 
    1028     2241157 : struct ImplBitmapDevice
    1029             : {
    1030             :     /** Bitmap memory plus deleter.
    1031             : 
    1032             :         Always points to the start of the mem
    1033             :      */
    1034             :     RawMemorySharedArray      mpMem;
    1035             : 
    1036             :     /// Palette memory plus deleter (might be NULL)
    1037             :     PaletteMemorySharedVector mpPalette;
    1038             : 
    1039             :     /** Bounds of the device.
    1040             : 
    1041             :         maBounds.getWidth()/getHeight() yield the true size of the
    1042             :         device (i.e. the rectangle given by maBounds covers the device
    1043             :         area under the including-the-bottommost-and-rightmost-pixels
    1044             :         fill rule)
    1045             :      */
    1046             :     basegfx::B2IBox           maBounds;
    1047             : 
    1048             :     //// Size of the actual frame buffer
    1049             :     basegfx::B2IVector        maBufferSize;
    1050             : 
    1051             :     /// Scanline format, as provided at the constructor
    1052             :     sal_Int32                 mnScanlineFormat;
    1053             : 
    1054             :     /// Scanline stride. Negative for bottom-to-top formats
    1055             :     sal_Int32                 mnScanlineStride;
    1056             : 
    1057             :     /// raw ptr to 0th scanline. used for cloning a generic renderer
    1058             :     sal_uInt8*                mpFirstScanline;
    1059             : 
    1060             :     /** (Optional) device sharing the same memory, and used for input
    1061             :         clip masks/alpha masks/bitmaps that don't match our exact
    1062             :         bitmap format.
    1063             : 
    1064             :         This is to avoid the combinatorical explosion when dealing
    1065             :         with n bitmap formats, which could be combined with n clip
    1066             :         masks, alpha masks and bitmap masks (yielding a total of n^4
    1067             :         combinations). Since each BitmapRenderer is specialized for
    1068             :         one specific combination of said formats, a lot of duplicate
    1069             :         code would be generated, most of which probably never
    1070             :         used. Therefore, only the most common combinations are
    1071             :         specialized templates, the remainder gets handled by this
    1072             :         generic renderer (via runtime polymorphism).
    1073             :      */
    1074             :     BitmapDeviceSharedPtr     mpGenericRenderer;
    1075             : };
    1076             : 
    1077             : 
    1078     1533564 : BitmapDevice::BitmapDevice( const basegfx::B2IBox&           rBounds,
    1079             :                             const basegfx::B2IVector&        rBufferSize,
    1080             :                             sal_Int32                        nScanlineFormat,
    1081             :                             sal_Int32                        nScanlineStride,
    1082             :                             sal_uInt8*                       pFirstScanline,
    1083             :                             const RawMemorySharedArray&      rMem,
    1084             :                             const PaletteMemorySharedVector& rPalette ) :
    1085     1533564 :     mpImpl( new ImplBitmapDevice )
    1086             : {
    1087     1533564 :     mpImpl->mpMem = rMem;
    1088     1533564 :     mpImpl->mpPalette = rPalette;
    1089     1533564 :     mpImpl->maBounds = rBounds;
    1090     1533564 :     mpImpl->maBufferSize = rBufferSize;
    1091     1533564 :     mpImpl->mnScanlineFormat = nScanlineFormat;
    1092     1533564 :     mpImpl->mnScanlineStride = nScanlineStride;
    1093     1533564 :     mpImpl->mpFirstScanline  = pFirstScanline;
    1094     1533564 : }
    1095             : 
    1096      707593 : BitmapDevice::~BitmapDevice()
    1097             : {
    1098             :     // outline, because of internal ImplBitmapDevice
    1099             :     SAL_INFO( "basebmp.bitmapdevice", "~BitmapDevice(" << this << ")" );
    1100      707593 : }
    1101             : 
    1102     4869648 : basegfx::B2IVector BitmapDevice::getSize() const
    1103             : {
    1104             :     return basegfx::B2IVector(
    1105     4869648 :         mpImpl->maBounds.getMaxX() - mpImpl->maBounds.getMinX(),
    1106     9739296 :         mpImpl->maBounds.getMaxY() - mpImpl->maBounds.getMinY() );
    1107             : }
    1108             : 
    1109     1096281 : bool BitmapDevice::isTopDown() const
    1110             : {
    1111     1096281 :     return mpImpl->mnScanlineStride >= 0;
    1112             : }
    1113             : 
    1114           0 : basegfx::B2IVector BitmapDevice::getBufferSize() const
    1115             : {
    1116           0 :     return mpImpl->maBufferSize;
    1117             : }
    1118             : 
    1119     3397562 : sal_Int32 BitmapDevice::getScanlineFormat() const
    1120             : {
    1121     3397562 :     return mpImpl->mnScanlineFormat;
    1122             : }
    1123             : 
    1124      581738 : sal_Int32 BitmapDevice::getScanlineStride() const
    1125             : {
    1126      581738 :     return mpImpl->mnScanlineStride < 0 ?
    1127      581738 :         -mpImpl->mnScanlineStride : mpImpl->mnScanlineStride;
    1128             : }
    1129             : 
    1130     2994819 : RawMemorySharedArray BitmapDevice::getBuffer() const
    1131             : {
    1132     2994819 :     return mpImpl->mpMem;
    1133             : }
    1134             : 
    1135      450488 : IBitmapDeviceDamageTrackerSharedPtr BitmapDevice::getDamageTracker() const
    1136             : {
    1137      450488 :     return getDamageTracker_i();
    1138             : }
    1139             : 
    1140           0 : void BitmapDevice::setDamageTracker( const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
    1141             : {
    1142           0 :     setDamageTracker_i(rDamage);
    1143           0 : }
    1144             : 
    1145      783655 : PaletteMemorySharedVector BitmapDevice::getPalette() const
    1146             : {
    1147      783655 :     return mpImpl->mpPalette;
    1148             : }
    1149             : 
    1150     1063266 : bool BitmapDevice::isSharedBuffer( const BitmapDeviceSharedPtr& rOther ) const
    1151             : {
    1152     1063266 :     return rOther.get()->getBuffer().get() == getBuffer().get();
    1153             : }
    1154             : 
    1155       14025 : void BitmapDevice::clear( Color fillColor )
    1156             : {
    1157       14025 :     clear_i( fillColor, mpImpl->maBounds );
    1158       14025 : }
    1159             : 
    1160      240819 : void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
    1161             :                              Color                    lineColor,
    1162             :                              DrawMode                 drawMode )
    1163             : {
    1164      240819 :     if( mpImpl->maBounds.isInside(rPt) )
    1165      220258 :         setPixel_i(rPt,lineColor,drawMode);
    1166      240819 : }
    1167             : 
    1168      295807 : void BitmapDevice::setPixel( const basegfx::B2IPoint&     rPt,
    1169             :                              Color                        lineColor,
    1170             :                              DrawMode                     drawMode,
    1171             :                              const BitmapDeviceSharedPtr& rClip )
    1172             : {
    1173      295807 :     if( !rClip )
    1174             :     {
    1175      240789 :         setPixel(rPt,lineColor,drawMode);
    1176      536596 :         return;
    1177             :     }
    1178             : 
    1179       55018 :     if( mpImpl->maBounds.isInside(rPt) )
    1180             :     {
    1181       55018 :         if( isCompatibleClipMask( rClip ) )
    1182       55018 :             setPixel_i(rPt,lineColor,drawMode,rClip);
    1183             :         else
    1184           0 :             getGenericRenderer()->setPixel( rPt, lineColor, drawMode, rClip );
    1185             :     }
    1186             : }
    1187             : 
    1188    82327657 : Color BitmapDevice::getPixel( const basegfx::B2IPoint& rPt )
    1189             : {
    1190    82327657 :     if( mpImpl->maBounds.isInside(rPt) )
    1191    82327657 :         return getPixel_i(rPt);
    1192             : 
    1193           0 :     return Color();
    1194             : }
    1195             : 
    1196           6 : sal_uInt32 BitmapDevice::getPixelData( const basegfx::B2IPoint& rPt )
    1197             : {
    1198           6 :     if( mpImpl->maBounds.isInside(rPt) )
    1199           4 :         return getPixelData_i(rPt);
    1200             : 
    1201           2 :     return 0;
    1202             : }
    1203             : 
    1204      565369 : void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
    1205             :                              const basegfx::B2IPoint& rPt2,
    1206             :                              Color                    lineColor,
    1207             :                              DrawMode                 drawMode )
    1208             : {
    1209             :     drawLine_i( rPt1,
    1210             :                 rPt2,
    1211      565369 :                 mpImpl->maBounds,
    1212             :                 lineColor,
    1213     1130738 :                 drawMode );
    1214      565369 : }
    1215             : 
    1216      572564 : void BitmapDevice::drawLine( const basegfx::B2IPoint&     rPt1,
    1217             :                              const basegfx::B2IPoint&     rPt2,
    1218             :                              Color                        lineColor,
    1219             :                              DrawMode                     drawMode,
    1220             :                              const BitmapDeviceSharedPtr& rClip )
    1221             : {
    1222      572564 :     if( !rClip )
    1223             :     {
    1224      565343 :         drawLine(rPt1,rPt2,lineColor,drawMode);
    1225     1137907 :         return;
    1226             :     }
    1227             : 
    1228        7221 :     if( isCompatibleClipMask( rClip ) )
    1229             :         drawLine_i( rPt1,
    1230             :                     rPt2,
    1231        7221 :                     mpImpl->maBounds,
    1232             :                     lineColor,
    1233             :                     drawMode,
    1234       14442 :                     rClip );
    1235             :     else
    1236             :         getGenericRenderer()->drawLine( rPt1, rPt2, lineColor,
    1237           0 :                                         drawMode, rClip );
    1238             : }
    1239             : 
    1240      163834 : void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
    1241             :                                 Color                      lineColor,
    1242             :                                 DrawMode                   drawMode )
    1243             : {
    1244      163834 :     const sal_uInt32 numVertices( rPoly.count() );
    1245      163834 :     if( numVertices )
    1246             :         drawPolygon_i( rPoly,
    1247      163834 :                        mpImpl->maBounds,
    1248      327668 :                        lineColor, drawMode );
    1249      163834 : }
    1250             : 
    1251      165093 : void BitmapDevice::drawPolygon( const basegfx::B2DPolygon&   rPoly,
    1252             :                                 Color                        lineColor,
    1253             :                                 DrawMode                     drawMode,
    1254             :                                 const BitmapDeviceSharedPtr& rClip )
    1255             : {
    1256      165093 :     if( !rClip )
    1257             :     {
    1258      163817 :         drawPolygon(rPoly,lineColor,drawMode);
    1259      328910 :         return;
    1260             :     }
    1261             : 
    1262        1276 :     const sal_uInt32 numVertices( rPoly.count() );
    1263        1276 :     if( numVertices )
    1264             :     {
    1265        1276 :         if( isCompatibleClipMask( rClip ) )
    1266             :             drawPolygon_i( rPoly,
    1267        1276 :                            mpImpl->maBounds,
    1268        2552 :                            lineColor, drawMode, rClip );
    1269             :         else
    1270             :             getGenericRenderer()->drawPolygon( rPoly, lineColor,
    1271           0 :                                                drawMode, rClip );
    1272             :     }
    1273             : }
    1274             : 
    1275     2104082 : void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
    1276             :                                     Color                          fillColor,
    1277             :                                     DrawMode                       drawMode )
    1278             : {
    1279     2104082 :     fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds );
    1280     2104082 : }
    1281             : 
    1282     2093820 : void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
    1283             :                                     Color                          fillColor,
    1284             :                                     DrawMode                       drawMode,
    1285             :                                     const BitmapDeviceSharedPtr&   rClip )
    1286             : {
    1287     2093820 :     if( !rClip )
    1288             :     {
    1289     2041979 :         fillPolyPolygon(rPoly,fillColor,drawMode);
    1290     4135799 :         return;
    1291             :     }
    1292             : 
    1293       51841 :     if( isCompatibleClipMask( rClip ) )
    1294       51841 :         fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds, rClip );
    1295             :     else
    1296             :         getGenericRenderer()->fillPolyPolygon( rPoly, fillColor,
    1297           0 :                                                drawMode, rClip );
    1298             : }
    1299             : 
    1300             : 
    1301             : namespace
    1302             : {
    1303      717489 :     void assertImagePoint( const basegfx::B2IPoint& rPt,
    1304             :                            const basegfx::B2IBox&   rPermittedRange )
    1305             :     {
    1306             :         (void)rPt; (void)rPermittedRange;
    1307             :         OSL_ASSERT( rPermittedRange.isInside(rPt) );
    1308      717489 :     }
    1309             : 
    1310     1419407 :     void assertImageRange( const basegfx::B2IBox& rRange,
    1311             :                            const basegfx::B2IBox& rPermittedRange )
    1312             :     {
    1313             : #if OSL_DEBUG_LEVEL > 0
    1314             :         basegfx::B2IBox aRange( rRange );
    1315             :         aRange.intersect( rPermittedRange );
    1316             : 
    1317             :         OSL_ASSERT( aRange == rRange );
    1318             : #else
    1319             :         (void)rRange; (void)rPermittedRange;
    1320             : #endif
    1321     1419407 :     }
    1322             : 
    1323             :     // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
    1324             :     // to basegfx, and use here!
    1325      825828 :     bool clipAreaImpl( ::basegfx::B2IBox&       io_rSourceArea,
    1326             :                        ::basegfx::B2IPoint&     io_rDestPoint,
    1327             :                        const ::basegfx::B2IBox& rSourceBounds,
    1328             :                        const ::basegfx::B2IBox& rDestBounds )
    1329             :     {
    1330             :         const ::basegfx::B2IPoint aSourceTopLeft(
    1331      825828 :             io_rSourceArea.getMinimum() );
    1332             : 
    1333      825828 :         ::basegfx::B2IBox aLocalSourceArea( io_rSourceArea );
    1334             : 
    1335             :         // clip source area (which must be inside rSourceBounds)
    1336      825828 :         aLocalSourceArea.intersect( rSourceBounds );
    1337             : 
    1338      825828 :         if( aLocalSourceArea.isEmpty() )
    1339           0 :             return false;
    1340             : 
    1341             :         // calc relative new source area points (relative to orig
    1342             :         // source area)
    1343             :         const ::basegfx::B2IVector aUpperLeftOffset(
    1344     1651656 :             aLocalSourceArea.getMinimum()-aSourceTopLeft );
    1345             :         const ::basegfx::B2IVector aLowerRightOffset(
    1346     1651656 :             aLocalSourceArea.getMaximum()-aSourceTopLeft );
    1347             : 
    1348     1651656 :         ::basegfx::B2IBox aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
    1349     2477484 :                                           io_rDestPoint + aLowerRightOffset );
    1350             : 
    1351             :         // clip dest area (which must be inside rDestBounds)
    1352      825828 :         aLocalDestArea.intersect( rDestBounds );
    1353             : 
    1354      825828 :         if( aLocalDestArea.isEmpty() )
    1355      108339 :             return false;
    1356             : 
    1357             :         // calc relative new dest area points (relative to orig
    1358             :         // source area)
    1359             :         const ::basegfx::B2IVector aDestUpperLeftOffset(
    1360     1434978 :             aLocalDestArea.getMinimum()-io_rDestPoint );
    1361             :         const ::basegfx::B2IVector aDestLowerRightOffset(
    1362     1434978 :             aLocalDestArea.getMaximum()-io_rDestPoint );
    1363             : 
    1364     1434978 :         io_rSourceArea = ::basegfx::B2IBox( aSourceTopLeft + aDestUpperLeftOffset,
    1365     2152467 :                                             aSourceTopLeft + aDestLowerRightOffset );
    1366      717489 :         io_rDestPoint  = aLocalDestArea.getMinimum();
    1367             : 
    1368     1543317 :         return true;
    1369             :     }
    1370             : 
    1371             :     // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
    1372             :     // to basegfx, and use here!
    1373      351664 :     bool clipAreaImpl( ::basegfx::B2IBox&       io_rDestArea,
    1374             :                        ::basegfx::B2IBox&       io_rSourceArea,
    1375             :                        const ::basegfx::B2IBox& rDestBounds,
    1376             :                        const ::basegfx::B2IBox& rSourceBounds )
    1377             :     {
    1378             :         // extract inherent scale
    1379      351664 :         const double nScaleX( io_rDestArea.getWidth() / (double)io_rSourceArea.getWidth() );
    1380      351664 :         const double nScaleY( io_rDestArea.getHeight() / (double)io_rSourceArea.getHeight() );
    1381             : 
    1382             :         // extract range origins
    1383             :         const basegfx::B2IPoint   aDestTopLeft(
    1384      351664 :             io_rDestArea.getMinimum() );
    1385             :         const ::basegfx::B2IPoint aSourceTopLeft(
    1386      703328 :             io_rSourceArea.getMinimum() );
    1387             : 
    1388      351664 :         ::basegfx::B2IBox aLocalSourceArea( io_rSourceArea );
    1389             : 
    1390             :         // clip source area (which must be inside rSourceBounds)
    1391      351664 :         aLocalSourceArea.intersect( rSourceBounds );
    1392             : 
    1393      351664 :         if( aLocalSourceArea.isEmpty() )
    1394           8 :             return false;
    1395             : 
    1396             :         // calc relative new source area points (relative to orig
    1397             :         // source area)
    1398             :         const ::basegfx::B2IVector aUpperLeftOffset(
    1399      703312 :             aLocalSourceArea.getMinimum()-aSourceTopLeft );
    1400             :         const ::basegfx::B2IVector aLowerRightOffset(
    1401      703312 :             aLocalSourceArea.getMaximum()-aSourceTopLeft );
    1402             : 
    1403      703312 :         ::basegfx::B2IBox aLocalDestArea( basegfx::fround(aDestTopLeft.getX() + nScaleX*aUpperLeftOffset.getX()),
    1404      703312 :                                           basegfx::fround(aDestTopLeft.getY() + nScaleY*aUpperLeftOffset.getY()),
    1405      703312 :                                           basegfx::fround(aDestTopLeft.getX() + nScaleX*aLowerRightOffset.getX()),
    1406     2461592 :                                           basegfx::fround(aDestTopLeft.getY() + nScaleY*aLowerRightOffset.getY()) );
    1407             : 
    1408             :         // clip dest area (which must be inside rDestBounds)
    1409      351656 :         aLocalDestArea.intersect( rDestBounds );
    1410             : 
    1411      351656 :         if( aLocalDestArea.isEmpty() )
    1412         697 :             return false;
    1413             : 
    1414             :         // calc relative new dest area points (relative to orig
    1415             :         // source area)
    1416             :         const ::basegfx::B2IVector aDestUpperLeftOffset(
    1417      701918 :             aLocalDestArea.getMinimum()-aDestTopLeft );
    1418             :         const ::basegfx::B2IVector aDestLowerRightOffset(
    1419      701918 :             aLocalDestArea.getMaximum()-aDestTopLeft );
    1420             : 
    1421      701918 :         io_rSourceArea = ::basegfx::B2IBox( basegfx::fround(aSourceTopLeft.getX() + aDestUpperLeftOffset.getX()/nScaleX),
    1422      701918 :                                             basegfx::fround(aSourceTopLeft.getY() + aDestUpperLeftOffset.getY()/nScaleY),
    1423      701918 :                                             basegfx::fround(aSourceTopLeft.getX() + aDestLowerRightOffset.getX()/nScaleX),
    1424     2456713 :                                             basegfx::fround(aSourceTopLeft.getY() + aDestLowerRightOffset.getY()/nScaleY) );
    1425      350959 :         io_rDestArea   = aLocalDestArea;
    1426             : 
    1427             :         // final source area clip (chopping round-offs)
    1428      350959 :         io_rSourceArea.intersect( rSourceBounds );
    1429             : 
    1430      350959 :         if( io_rSourceArea.isEmpty() )
    1431           0 :             return false;
    1432             : 
    1433             : 
    1434      702623 :         return true;
    1435             :     }
    1436             : }
    1437             : 
    1438      345118 : void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
    1439             :                                const basegfx::B2IBox&       rSrcRect,
    1440             :                                const basegfx::B2IBox&       rDstRect,
    1441             :                                DrawMode                     drawMode )
    1442             : {
    1443      345118 :     const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
    1444      345118 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1445      345118 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1446      345118 :     basegfx::B2IBox           aDestRange( rDstRect );
    1447             : 
    1448      345118 :     if( clipAreaImpl( aDestRange,
    1449             :                       aSrcRange,
    1450      345118 :                       mpImpl->maBounds,
    1451      345118 :                       aSrcBounds ))
    1452             :     {
    1453      344413 :         assertImageRange(aDestRange,mpImpl->maBounds);
    1454      344413 :         assertImageRange(aSrcRange,aSrcBounds);
    1455             : 
    1456      344413 :         drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode );
    1457      345118 :     }
    1458      345118 : }
    1459             : 
    1460      133669 : void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
    1461             :                                const basegfx::B2IBox&       rSrcRect,
    1462             :                                const basegfx::B2IBox&       rDstRect,
    1463             :                                DrawMode                     drawMode,
    1464             :                                const BitmapDeviceSharedPtr& rClip )
    1465             : {
    1466      133669 :     if( !rClip )
    1467             :     {
    1468      132307 :         drawBitmap(rSrcBitmap,rSrcRect,rDstRect,drawMode);
    1469      265976 :         return;
    1470             :     }
    1471             : 
    1472        1362 :     const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
    1473        1362 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1474        1362 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1475        1362 :     basegfx::B2IBox           aDestRange( rDstRect );
    1476             : 
    1477        1362 :     if( clipAreaImpl( aDestRange,
    1478             :                       aSrcRange,
    1479        1362 :                       mpImpl->maBounds,
    1480        1362 :                       aSrcBounds ))
    1481             :     {
    1482        1362 :         assertImageRange(aDestRange,mpImpl->maBounds);
    1483        1362 :         assertImageRange(aSrcRange,aSrcBounds);
    1484             : 
    1485        1362 :         if( isCompatibleClipMask( rClip ) )
    1486             :         {
    1487        1362 :             drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode, rClip );
    1488             :         }
    1489             :         else
    1490             :         {
    1491             :             getGenericRenderer()->drawBitmap( rSrcBitmap, rSrcRect,
    1492           0 :                                               rDstRect, drawMode, rClip );
    1493             :         }
    1494        1362 :     }
    1495             : }
    1496             : 
    1497      824719 : void BitmapDevice::drawMaskedColor( Color                        aSrcColor,
    1498             :                                     const BitmapDeviceSharedPtr& rAlphaMask,
    1499             :                                     const basegfx::B2IBox&       rSrcRect,
    1500             :                                     const basegfx::B2IPoint&     rDstPoint )
    1501             : {
    1502      824719 :     const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
    1503      824719 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1504      824719 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1505     1649438 :     basegfx::B2IPoint         aDestPoint( rDstPoint );
    1506             : 
    1507      824719 :     if( clipAreaImpl( aSrcRange,
    1508             :                       aDestPoint,
    1509             :                       aSrcBounds,
    1510      824719 :                       mpImpl->maBounds ))
    1511             :     {
    1512      716380 :         assertImagePoint(aDestPoint,mpImpl->maBounds);
    1513      716380 :         assertImageRange(aSrcRange,aSrcBounds);
    1514             : 
    1515      716380 :         if( isSharedBuffer(rAlphaMask) )
    1516             :         {
    1517             :             // src == dest, copy rAlphaMask beforehand
    1518             :             // ---------------------------------------------------
    1519             : 
    1520           0 :             const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
    1521           0 :                                            aSrcRange.getHeight() );
    1522             :             BitmapDeviceSharedPtr pAlphaCopy(
    1523             :                 cloneBitmapDevice( aSize,
    1524           0 :                                    shared_from_this()) );
    1525           0 :             basegfx::B2ITuple aGcc3WorkaroundTemporary;
    1526             :             const basegfx::B2IBox aAlphaRange( aGcc3WorkaroundTemporary,
    1527           0 :                                                aSize );
    1528             :             pAlphaCopy->drawBitmap(rAlphaMask,
    1529             :                                    aSrcRange,
    1530             :                                    aAlphaRange,
    1531           0 :                                    DrawMode_PAINT);
    1532           0 :             drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint );
    1533             :         }
    1534             :         else
    1535             :         {
    1536      716380 :             drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint );
    1537             :         }
    1538      824719 :     }
    1539      824719 : }
    1540             : 
    1541      825820 : void BitmapDevice::drawMaskedColor( Color                        aSrcColor,
    1542             :                                     const BitmapDeviceSharedPtr& rAlphaMask,
    1543             :                                     const basegfx::B2IBox&       rSrcRect,
    1544             :                                     const basegfx::B2IPoint&     rDstPoint,
    1545             :                                     const BitmapDeviceSharedPtr& rClip )
    1546             : {
    1547      825820 :     if( !rClip )
    1548             :     {
    1549      824711 :         drawMaskedColor(aSrcColor,rAlphaMask,rSrcRect,rDstPoint);
    1550     1650531 :         return;
    1551             :     }
    1552             : 
    1553        1109 :     const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
    1554        1109 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1555        1109 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1556        2218 :     basegfx::B2IPoint         aDestPoint( rDstPoint );
    1557             : 
    1558        1109 :     if( clipAreaImpl( aSrcRange,
    1559             :                       aDestPoint,
    1560             :                       aSrcBounds,
    1561        1109 :                       mpImpl->maBounds ))
    1562             :     {
    1563        1109 :         assertImagePoint(aDestPoint,mpImpl->maBounds);
    1564        1109 :         assertImageRange(aSrcRange,aSrcBounds);
    1565             : 
    1566        1109 :         if( isCompatibleClipMask( rClip ) )
    1567             :         {
    1568        1109 :             if( isSharedBuffer(rAlphaMask) )
    1569             :             {
    1570             :                 // src == dest, copy rAlphaMask beforehand
    1571             :                 // ---------------------------------------------------
    1572             : 
    1573           0 :                 const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
    1574           0 :                                                aSrcRange.getHeight() );
    1575             :                 BitmapDeviceSharedPtr pAlphaCopy(
    1576             :                     cloneBitmapDevice( aSize,
    1577           0 :                                        shared_from_this()) );
    1578           0 :                 basegfx::B2ITuple aGcc3WorkaroundTemporary;
    1579             :                 const basegfx::B2IBox aAlphaRange( aGcc3WorkaroundTemporary,
    1580           0 :                                                    aSize );
    1581             :                 pAlphaCopy->drawBitmap(rAlphaMask,
    1582             :                                        aSrcRange,
    1583             :                                        aAlphaRange,
    1584           0 :                                        DrawMode_PAINT);
    1585           0 :                 drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint, rClip );
    1586             :             }
    1587             :             else
    1588             :             {
    1589        1109 :                 drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint, rClip );
    1590             :             }
    1591             :         }
    1592             :         else
    1593             :         {
    1594             :             getGenericRenderer()->drawMaskedColor( aSrcColor, rAlphaMask,
    1595           0 :                                                    rSrcRect, rDstPoint, rClip );
    1596             :         }
    1597        1109 :     }
    1598             : }
    1599             : 
    1600        5184 : void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
    1601             :                                      const BitmapDeviceSharedPtr& rMask,
    1602             :                                      const basegfx::B2IBox&       rSrcRect,
    1603             :                                      const basegfx::B2IBox&       rDstRect,
    1604             :                                      DrawMode                     drawMode )
    1605             : {
    1606             :     OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
    1607             : 
    1608        5184 :     const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
    1609        5184 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1610        5184 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1611        5184 :     basegfx::B2IBox           aDestRange( rDstRect );
    1612             : 
    1613        5184 :     if( clipAreaImpl( aDestRange,
    1614             :                       aSrcRange,
    1615        5184 :                       mpImpl->maBounds,
    1616        5184 :                       aSrcBounds ))
    1617             :     {
    1618        5184 :         assertImageRange(aDestRange,mpImpl->maBounds);
    1619        5184 :         assertImageRange(aSrcRange,aSrcBounds);
    1620             : 
    1621        5184 :         drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode );
    1622        5184 :     }
    1623        5184 : }
    1624             : 
    1625        5180 : void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
    1626             :                                      const BitmapDeviceSharedPtr& rMask,
    1627             :                                      const basegfx::B2IBox&       rSrcRect,
    1628             :                                      const basegfx::B2IBox&       rDstRect,
    1629             :                                      DrawMode                     drawMode,
    1630             :                                      const BitmapDeviceSharedPtr& rClip )
    1631             : {
    1632        5180 :     if( !rClip )
    1633             :     {
    1634        5180 :         drawMaskedBitmap(rSrcBitmap,rMask,rSrcRect,rDstRect,drawMode);
    1635       10360 :         return;
    1636             :     }
    1637             : 
    1638             :     OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
    1639             : 
    1640           0 :     const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
    1641           0 :     const basegfx::B2IBox     aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
    1642           0 :     basegfx::B2IBox           aSrcRange( rSrcRect );
    1643           0 :     basegfx::B2IBox           aDestRange( rDstRect );
    1644             : 
    1645           0 :     if( clipAreaImpl( aDestRange,
    1646             :                       aSrcRange,
    1647           0 :                       mpImpl->maBounds,
    1648           0 :                       aSrcBounds ))
    1649             :     {
    1650           0 :         assertImageRange(aDestRange,mpImpl->maBounds);
    1651           0 :         assertImageRange(aSrcRange,aSrcBounds);
    1652             : 
    1653           0 :         if( isCompatibleClipMask( rClip ) )
    1654             :         {
    1655           0 :             drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode, rClip );
    1656             :         }
    1657             :         else
    1658             :         {
    1659             :             getGenericRenderer()->drawMaskedBitmap( rSrcBitmap, rMask, rSrcRect,
    1660           0 :                                                     rDstRect, drawMode, rClip );
    1661             :         }
    1662           0 :     }
    1663             : }
    1664             : 
    1665             : 
    1666             : //----------------------------------------------------------------------------------
    1667             : 
    1668             : /** Standard clip and alpha masks
    1669             :  */
    1670             : struct StdMasks
    1671             : {
    1672             :     typedef PixelFormatTraits_GREY1_MSB   clipmask_format_traits;
    1673             :     typedef PixelFormatTraits_GREY8       alphamask_format_traits;
    1674             : 
    1675             :     /// Clipmask: 0 means opaque
    1676             :     static const bool clipmask_polarity  = false;
    1677             : 
    1678             :     /// Alpha mask: 0 means fully transparent
    1679             :     static const bool alphamask_polarity = true;
    1680             : };
    1681             : 
    1682             : //----------------------------------------------------------------------------------
    1683             : 
    1684             : // Some compilers don't like the nested template wrap_accessor
    1685             : // reference in the parameter list - being slightly less type safe,
    1686             : // then.
    1687             : #ifndef BASEBMP_NO_NESTED_TEMPLATE_PARAMETER
    1688             : 
    1689             : /// Produces a specialized renderer for the given pixel format
    1690             : template< class FormatTraits, class MaskTraits >
    1691     1533564 : BitmapDeviceSharedPtr createRenderer(
    1692             :     const basegfx::B2IBox&                                       rBounds,
    1693             :     const basegfx::B2IVector&                                    rBufferSize,
    1694             :     sal_Int32                                                    nScanlineFormat,
    1695             :     sal_Int32                                                    nScanlineStride,
    1696             :     sal_uInt8*                                                   pFirstScanline,
    1697             :     typename FormatTraits::raw_accessor_type const&              rRawAccessor,
    1698             :     typename FormatTraits::accessor_selector::template wrap_accessor<
    1699             :           typename FormatTraits::raw_accessor_type>::type const& rAccessor,
    1700             :     boost::shared_array< sal_uInt8 >                             pMem,
    1701             :     const PaletteMemorySharedVector&                             pPal,
    1702             :     const IBitmapDeviceDamageTrackerSharedPtr&                   pDamage )
    1703             : #else
    1704             : 
    1705             : template< class FormatTraits, class MaskTraits, class Accessor >
    1706             : BitmapDeviceSharedPtr createRenderer(
    1707             :     const basegfx::B2IBox&                                       rBounds,
    1708             :     const basegfx::B2IVector&                                    rBufferSize,
    1709             :     sal_Int32                                                    nScanlineFormat,
    1710             :     sal_Int32                                                    nScanlineStride,
    1711             :     sal_uInt8*                                                   pFirstScanline,
    1712             :     typename FormatTraits::raw_accessor_type const&              rRawAccessor,
    1713             :     Accessor const&                                              rAccessor,
    1714             :     boost::shared_array< sal_uInt8 >                             pMem,
    1715             :     const PaletteMemorySharedVector&                             pPal,
    1716             :     const IBitmapDeviceDamageTrackerSharedPtr&                   pDamage )
    1717             : 
    1718             : #endif
    1719             : {
    1720             :     typedef typename FormatTraits::iterator_type                Iterator;
    1721             :     typedef BitmapRenderer< Iterator,
    1722             :                             typename FormatTraits::raw_accessor_type,
    1723             :                             typename FormatTraits::accessor_selector,
    1724             :                             MaskTraits >                        Renderer;
    1725             : 
    1726             :     return BitmapDeviceSharedPtr(
    1727             :         new Renderer( rBounds,
    1728             :                       rBufferSize,
    1729             :                       nScanlineFormat,
    1730             :                       nScanlineStride,
    1731             :                       pFirstScanline,
    1732             :                       Iterator(
    1733             :                           reinterpret_cast<typename Iterator::value_type*>(
    1734             :                               pFirstScanline),
    1735             :                           nScanlineStride),
    1736             :                       rRawAccessor,
    1737             :                       rAccessor,
    1738             :                       pMem,
    1739             :                       pPal,
    1740     1533564 :                       pDamage ));
    1741             : }
    1742             : 
    1743             : /// Create standard grey level palette
    1744      144814 : PaletteMemorySharedVector createStandardPalette(
    1745             :     const PaletteMemorySharedVector& pPal,
    1746             :     sal_Int32                        nNumEntries )
    1747             : {
    1748      144814 :     if( pPal || nNumEntries <= 0 )
    1749      144778 :         return pPal;
    1750             : 
    1751             :     boost::shared_ptr< std::vector<Color> > pLocalPal(
    1752          36 :         new std::vector<Color>(nNumEntries) );
    1753             : 
    1754          36 :     const sal_Int32 nIncrement( 0x00FFFFFF/nNumEntries );
    1755          36 :     --nNumEntries;
    1756          72 :     for( sal_Int32 i=0, c=0; i<nNumEntries; ++i,c+=nIncrement )
    1757          36 :         pLocalPal->at(i) = Color(0xFF000000 | c);
    1758             : 
    1759          36 :     pLocalPal->at(nNumEntries) = Color(0xFFFFFFFF);
    1760             : 
    1761          36 :     return pLocalPal;
    1762             : }
    1763             : 
    1764             : template< class FormatTraits, class MaskTraits >
    1765     1388750 : BitmapDeviceSharedPtr createRenderer(
    1766             :     const basegfx::B2IBox&                     rBounds,
    1767             :     const basegfx::B2IVector&                  rBufferSize,
    1768             :     sal_Int32                                  nScanlineFormat,
    1769             :     sal_Int32                                  nScanlineStride,
    1770             :     sal_uInt8*                                 pFirstScanline,
    1771             :     boost::shared_array< sal_uInt8 >           pMem,
    1772             :     const PaletteMemorySharedVector&           pPal,
    1773             :     const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
    1774             : {
    1775             :     return createRenderer<FormatTraits,
    1776             :                           MaskTraits>(rBounds,
    1777             :                                       rBufferSize,
    1778             :                                       nScanlineFormat,
    1779             :                                       nScanlineStride,
    1780             :                                       pFirstScanline,
    1781             :                                       typename FormatTraits::raw_accessor_type(),
    1782             :                                       typename FormatTraits::accessor_selector::template
    1783             :                                       wrap_accessor<
    1784             :                                           typename FormatTraits::raw_accessor_type>::type(),
    1785             :                                       pMem,
    1786             :                                       pPal,
    1787     1388750 :                                       pDamage);
    1788             : }
    1789             : 
    1790             : template< class FormatTraits, class MaskTraits >
    1791      144814 : BitmapDeviceSharedPtr createRenderer(
    1792             :     const basegfx::B2IBox&                     rBounds,
    1793             :     const basegfx::B2IVector&                  rBufferSize,
    1794             :     sal_Int32                                  nScanlineFormat,
    1795             :     sal_Int32                                  nScanlineStride,
    1796             :     sal_uInt8*                                 pFirstScanline,
    1797             :     boost::shared_array< sal_uInt8 >           pMem,
    1798             :     PaletteMemorySharedVector                  pPal,
    1799             :     int                                        nBitsPerPixel,
    1800             :     const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
    1801             : {
    1802      144814 :     pPal = createStandardPalette(pPal,
    1803             :                                  1UL << nBitsPerPixel);
    1804             : 
    1805             :     OSL_ASSERT(pPal);
    1806             :     return createRenderer<FormatTraits,
    1807             :                           MaskTraits>(rBounds,
    1808             :                                       rBufferSize,
    1809             :                                       nScanlineFormat,
    1810             :                                       nScanlineStride,
    1811             :                                       pFirstScanline,
    1812             :                                       typename FormatTraits::raw_accessor_type(),
    1813             :                                       typename FormatTraits::accessor_selector::template
    1814             :                                           wrap_accessor<
    1815             :                                       typename FormatTraits::raw_accessor_type>::type(
    1816      144814 :                                           &pPal->at(0),
    1817             :                                           pPal->size()),
    1818             :                                       pMem,
    1819             :                                       pPal,
    1820      289628 :                                       pDamage);
    1821             : }
    1822             : 
    1823             : //----------------------------------------------------------------------------------
    1824             : 
    1825             : // TODO(Q3): consolidate with canvas/canvastools.hxx! Best move this
    1826             : // to o3tl or sal/bithacks.hxx ...
    1827             : 
    1828             : /** Compute the next highest power of 2 of a 32-bit value
    1829             : 
    1830             :     Code devised by Sean Anderson, in good ole HAKMEM
    1831             :     tradition.
    1832             : 
    1833             :     @return 1 << (lg(x - 1) + 1)
    1834             : */
    1835     1533567 : inline sal_uInt32 nextPow2( sal_uInt32 x )
    1836             : {
    1837     1533567 :     --x;
    1838     1533567 :     x |= x >> 1;
    1839     1533567 :     x |= x >> 2;
    1840     1533567 :     x |= x >> 4;
    1841     1533567 :     x |= x >> 8;
    1842     1533567 :     x |= x >> 16;
    1843             : 
    1844     1533567 :     return ++x;
    1845             : }
    1846             : 
    1847             : //----------------------------------------------------------------------------------
    1848             : 
    1849             : namespace
    1850             : {
    1851     1533567 : BitmapDeviceSharedPtr createBitmapDeviceImplInner( const basegfx::B2IVector&                  rSize,
    1852             :                                                    bool                                       bTopDown,
    1853             :                                                    sal_Int32                                  nScanlineFormat,
    1854             :                                                    boost::shared_array< sal_uInt8 >           pMem,
    1855             :                                                    PaletteMemorySharedVector                  pPal,
    1856             :                                                    const basegfx::B2IBox*                     pSubset,
    1857             :                                                    const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
    1858             : {
    1859             :     OSL_ASSERT(rSize.getX() > 0 && rSize.getY() > 0);
    1860             : 
    1861     1533567 :     if( nScanlineFormat <= Format::NONE ||
    1862             :         nScanlineFormat >  Format::MAX )
    1863           0 :         return BitmapDeviceSharedPtr();
    1864             : 
    1865             :     static const sal_uInt8 bitsPerPixel[] =
    1866             :     {
    1867             :         0,  // NONE
    1868             :         1,  // ONE_BIT_MSB_GREY
    1869             :         1,  // ONE_BIT_LSB_GREY
    1870             :         1,  // ONE_BIT_MSB_PAL
    1871             :         1,  // ONE_BIT_LSB_PAL
    1872             :         4,  // FOUR_BIT_MSB_GREY
    1873             :         4,  // FOUR_BIT_LSB_GREY
    1874             :         4,  // FOUR_BIT_MSB_PAL
    1875             :         4,  // FOUR_BIT_LSB_PAL
    1876             :         8,  // EIGHT_BIT_PAL
    1877             :         8,  // EIGHT_BIT_GREY
    1878             :         16, // SIXTEEN_BIT_LSB_TC_MASK
    1879             :         16, // SIXTEEN_BIT_MSB_TC_MASK
    1880             :         24, // TWENTYFOUR_BIT_TC_MASK
    1881             :         32, // THIRTYTWO_BIT_TC_MASK_BGRA
    1882             :         32, // THIRTYTWO_BIT_TC_MASK_ARGB
    1883             :         32, // THIRTYTWO_BIT_TC_MASK_ABGR
    1884             :         32, // THIRTYTWO_BIT_TC_MASK_RGBA
    1885             :    };
    1886             : 
    1887     1533567 :     sal_Int32  nScanlineStride(0);
    1888             : 
    1889             :     // round up to full 8 bit, divide by 8
    1890     1533567 :     nScanlineStride = (rSize.getX()*bitsPerPixel[nScanlineFormat] + 7) >> 3;
    1891             : 
    1892             :     // rounded up to next full power-of-two number of bytes
    1893             :     const sal_uInt32 bytesPerPixel = nextPow2(
    1894     1533567 :         (bitsPerPixel[nScanlineFormat] + 7) >> 3);
    1895             : 
    1896             :     // now make nScanlineStride a multiple of bytesPerPixel
    1897     1533567 :     nScanlineStride = (nScanlineStride + bytesPerPixel - 1) / bytesPerPixel * bytesPerPixel;
    1898             : 
    1899             :     // factor in bottom-up scanline order case
    1900     1533567 :     nScanlineStride *= bTopDown ? 1 : -1;
    1901             : 
    1902     1533567 :     const sal_uInt32 nWidth(nScanlineStride < 0 ? -nScanlineStride : nScanlineStride);
    1903     1533567 :     const sal_uInt32 nHeight(rSize.getY());
    1904             : 
    1905     1533567 :     if (nHeight && nWidth && nWidth > SAL_MAX_INT32 / nHeight)
    1906             :     {
    1907             :         SAL_WARN( "basebmp", "suspicious massive alloc " << nWidth << " * " << nHeight);
    1908           3 :         return BitmapDeviceSharedPtr();
    1909             :     }
    1910             : 
    1911     1533564 :     const std::size_t nMemSize(nWidth * nHeight);
    1912             : 
    1913     1533564 :     if( !pMem )
    1914             :     {
    1915             :         pMem.reset(
    1916      421202 :             reinterpret_cast<sal_uInt8*>(rtl_allocateMemory( nMemSize )),
    1917      421202 :             &rtl_freeMemory );
    1918      421202 :         if (pMem.get() == 0 && nMemSize != 0)
    1919           0 :             return BitmapDeviceSharedPtr();
    1920      421202 :         memset(pMem.get(), 0, nMemSize);
    1921             :     }
    1922             : 
    1923             :     sal_uInt8* pFirstScanline = nScanlineStride < 0 ?
    1924     1533564 :         pMem.get() + nMemSize + nScanlineStride : pMem.get();
    1925             : 
    1926             :     // shrink render area to given subset, if given
    1927     1533564 :     basegfx::B2IBox aBounds(0,0,rSize.getX(),rSize.getY());
    1928     1533564 :     if( pSubset )
    1929      222489 :         aBounds.intersect( *pSubset );
    1930             : 
    1931     1533564 :     switch( nScanlineFormat )
    1932             :     {
    1933             :         // ----------------------------------------------------------------------
    1934             :         // one bit formats
    1935             : 
    1936             :         case Format::ONE_BIT_MSB_GREY:
    1937             :             return createRenderer<PixelFormatTraits_GREY1_MSB,StdMasks>(
    1938             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1939       13958 :                 pFirstScanline, pMem, pPal, rDamage );
    1940             : 
    1941             :         case Format::ONE_BIT_LSB_GREY:
    1942             :             return createRenderer<PixelFormatTraits_GREY1_LSB,StdMasks>(
    1943             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1944           3 :                 pFirstScanline, pMem, pPal, rDamage );
    1945             : 
    1946             :         case Format::ONE_BIT_MSB_PAL:
    1947             :             return createRenderer<PixelFormatTraits_PAL1_MSB,StdMasks>(
    1948             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1949             :                 pFirstScanline, pMem, pPal,
    1950       15204 :                 bitsPerPixel[nScanlineFormat], rDamage );
    1951             : 
    1952             :         case Format::ONE_BIT_LSB_PAL:
    1953             :             return createRenderer<PixelFormatTraits_PAL1_LSB,StdMasks>(
    1954             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1955             :                 pFirstScanline, pMem, pPal,
    1956           1 :                 bitsPerPixel[nScanlineFormat], rDamage );
    1957             : 
    1958             : 
    1959             :         // ----------------------------------------------------------------------
    1960             :         // four bit formats
    1961             : 
    1962             :         case Format::FOUR_BIT_MSB_GREY:
    1963             :             return createRenderer<PixelFormatTraits_GREY4_MSB,StdMasks>(
    1964             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1965           0 :                 pFirstScanline, pMem, pPal, rDamage );
    1966             : 
    1967             :         case Format::FOUR_BIT_LSB_GREY:
    1968             :             return createRenderer<PixelFormatTraits_GREY4_LSB,StdMasks>(
    1969             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1970           0 :                 pFirstScanline, pMem, pPal, rDamage );
    1971             : 
    1972             :         case Format::FOUR_BIT_MSB_PAL:
    1973             :             return createRenderer<PixelFormatTraits_PAL4_MSB,StdMasks>(
    1974             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1975             :                 pFirstScanline, pMem, pPal,
    1976         350 :                 bitsPerPixel[nScanlineFormat], rDamage );
    1977             : 
    1978             :         case Format::FOUR_BIT_LSB_PAL:
    1979             :             return createRenderer<PixelFormatTraits_PAL4_LSB,StdMasks>(
    1980             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1981             :                 pFirstScanline, pMem, pPal,
    1982           0 :                 bitsPerPixel[nScanlineFormat], rDamage );
    1983             : 
    1984             : 
    1985             :         // ----------------------------------------------------------------------
    1986             :         // eight bit formats
    1987             : 
    1988             :         case Format::EIGHT_BIT_GREY:
    1989             :             return createRenderer<PixelFormatTraits_GREY8,StdMasks>(
    1990             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1991      825820 :                 pFirstScanline, pMem, pPal, rDamage );
    1992             : 
    1993             :         case Format::EIGHT_BIT_PAL:
    1994             :             return createRenderer<PixelFormatTraits_PAL8,StdMasks>(
    1995             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    1996             :                 pFirstScanline, pMem, pPal,
    1997      129259 :                 bitsPerPixel[nScanlineFormat], rDamage );
    1998             : 
    1999             : 
    2000             :         // ----------------------------------------------------------------------
    2001             :         // sixteen bit formats
    2002             : 
    2003             :         case Format::SIXTEEN_BIT_LSB_TC_MASK:
    2004             :             return createRenderer<PixelFormatTraits_RGB16_565_LSB,StdMasks>(
    2005             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2006           1 :                 pFirstScanline, pMem, pPal, rDamage );
    2007             : 
    2008             :         case Format::SIXTEEN_BIT_MSB_TC_MASK:
    2009             :             return createRenderer<PixelFormatTraits_RGB16_565_MSB,StdMasks>(
    2010             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2011           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2012             : 
    2013             : 
    2014             :         // ----------------------------------------------------------------------
    2015             :         // twentyfour bit formats
    2016             :         case Format::TWENTYFOUR_BIT_TC_MASK:
    2017             :             return createRenderer<PixelFormatTraits_BGR24,StdMasks>(
    2018             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2019      548932 :                 pFirstScanline, pMem, pPal, rDamage );
    2020             : 
    2021             : 
    2022             :         // ----------------------------------------------------------------------
    2023             :         // thirtytwo bit formats
    2024             : 
    2025             :         case Format::THIRTYTWO_BIT_TC_MASK_BGRA:
    2026             :             return createRenderer<PixelFormatTraits_BGRX32_8888,StdMasks>(
    2027             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2028          36 :                 pFirstScanline, pMem, pPal, rDamage );
    2029             : 
    2030             :         case Format::THIRTYTWO_BIT_TC_MASK_ARGB:
    2031             :             return createRenderer<PixelFormatTraits_XRGB32_8888,StdMasks>(
    2032             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2033           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2034             : 
    2035             :         case Format::THIRTYTWO_BIT_TC_MASK_ABGR:
    2036             :             return createRenderer<PixelFormatTraits_XBGR32_8888,StdMasks>(
    2037             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2038           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2039             : 
    2040             :         case Format::THIRTYTWO_BIT_TC_MASK_RGBA:
    2041             :             return createRenderer<PixelFormatTraits_RGBX32_8888,StdMasks>(
    2042             :                 aBounds, rSize, nScanlineFormat, nScanlineStride,
    2043           0 :                 pFirstScanline, pMem, pPal, rDamage );
    2044             :     }
    2045             : 
    2046             :     // TODO(F3): other formats not yet implemented
    2047           0 :     return BitmapDeviceSharedPtr();
    2048             : }
    2049             : 
    2050     1533567 : BitmapDeviceSharedPtr createBitmapDeviceImpl( const basegfx::B2IVector&                  rSize,
    2051             :                                               bool                                       bTopDown,
    2052             :                                               sal_Int32                                  nScanlineFormat,
    2053             :                                               boost::shared_array< sal_uInt8 >           pMem,
    2054             :                                               PaletteMemorySharedVector                  pPal,
    2055             :                                               const basegfx::B2IBox*                     pSubset,
    2056             :                                               const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
    2057             : {
    2058     1533567 :     BitmapDeviceSharedPtr result( createBitmapDeviceImplInner( rSize, bTopDown, nScanlineFormat, pMem, pPal, pSubset, rDamage ) );
    2059             : 
    2060             : #ifdef SAL_LOG_INFO
    2061             :     std::ostringstream subset;
    2062             : 
    2063             :     if (pSubset)
    2064             :         subset << " subset=" << pSubset->getWidth() << "x" << pSubset->getHeight() << "@(" << pSubset->getMinX() << "," << pSubset->getMinY() << ")";
    2065             : 
    2066             :     SAL_INFO( "basebmp.bitmapdevice",
    2067             :               "createBitmapDevice: "
    2068             :               << rSize.getX() << "x" << rSize.getY()
    2069             :               << (bTopDown ? " top-down " : " bottom-up ")
    2070             :               << Format::formatName(nScanlineFormat)
    2071             :               << subset.str()
    2072             :               << " = " << result.get() );
    2073             : #endif
    2074     1533567 :     return result;
    2075             : }
    2076             : } // namespace
    2077             : 
    2078             : 
    2079      133988 : BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
    2080             :                                           bool                      bTopDown,
    2081             :                                           sal_Int32                 nScanlineFormat )
    2082             : {
    2083             :     return createBitmapDeviceImpl( rSize,
    2084             :                                    bTopDown,
    2085             :                                    nScanlineFormat,
    2086             :                                    boost::shared_array< sal_uInt8 >(),
    2087             :                                    PaletteMemorySharedVector(),
    2088             :                                    NULL,
    2089      133988 :                                    IBitmapDeviceDamageTrackerSharedPtr() );
    2090             : }
    2091             : 
    2092        7187 : BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector&        rSize,
    2093             :                                           bool                             bTopDown,
    2094             :                                           sal_Int32                        nScanlineFormat,
    2095             :                                           const PaletteMemorySharedVector& rPalette )
    2096             : {
    2097             :     return createBitmapDeviceImpl( rSize,
    2098             :                                    bTopDown,
    2099             :                                    nScanlineFormat,
    2100             :                                    boost::shared_array< sal_uInt8 >(),
    2101             :                                    rPalette,
    2102             :                                    NULL,
    2103        7187 :                                    IBitmapDeviceDamageTrackerSharedPtr() );
    2104             : }
    2105             : 
    2106      941904 : BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector&        rSize,
    2107             :                                           bool                             bTopDown,
    2108             :                                           sal_Int32                        nScanlineFormat,
    2109             :                                           const RawMemorySharedArray&      rMem,
    2110             :                                           const PaletteMemorySharedVector& rPalette )
    2111             : {
    2112             :     return createBitmapDeviceImpl( rSize,
    2113             :                                    bTopDown,
    2114             :                                    nScanlineFormat,
    2115             :                                    rMem,
    2116             :                                    rPalette,
    2117             :                                    NULL,
    2118      941904 :                                    IBitmapDeviceDamageTrackerSharedPtr() );
    2119             : }
    2120             : 
    2121      222489 : BitmapDeviceSharedPtr subsetBitmapDevice( const BitmapDeviceSharedPtr& rProto,
    2122             :                                           const basegfx::B2IBox&       rSubset )
    2123             : {
    2124             :     SAL_INFO( "basebmp.bitmapdevice", "subsetBitmapDevice: proto=" << rProto.get() );
    2125             :     return createBitmapDeviceImpl( rProto->getSize(),
    2126      222489 :                                    rProto->isTopDown(),
    2127             :                                    rProto->getScanlineFormat(),
    2128             :                                    rProto->getBuffer(),
    2129             :                                    rProto->getPalette(),
    2130             :                                    &rSubset,
    2131      444978 :                                    rProto->getDamageTracker() );
    2132             : }
    2133             : 
    2134      227999 : BitmapDeviceSharedPtr cloneBitmapDevice( const basegfx::B2IVector&    rSize,
    2135             :                                          const BitmapDeviceSharedPtr& rProto )
    2136             : {
    2137             :     return createBitmapDeviceImpl( rSize,
    2138      227999 :                                    rProto->isTopDown(),
    2139             :                                    rProto->getScanlineFormat(),
    2140             :                                    boost::shared_array< sal_uInt8 >(),
    2141             :                                    rProto->getPalette(),
    2142             :                                    NULL,
    2143      455998 :                                    rProto->getDamageTracker() );
    2144             : }
    2145             : 
    2146             : //----------------------------------------------------------------------------------
    2147             : 
    2148             : /// Clone our device, with GenericImageAccessor to handle all formats
    2149           0 : BitmapDeviceSharedPtr BitmapDevice::getGenericRenderer() const
    2150             : {
    2151           0 :     return mpImpl->mpGenericRenderer;
    2152             : }
    2153             : 
    2154             : } // namespace basebmp
    2155             : 
    2156             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10