1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include "basebmp/bitmapdevice.hxx"
24 #include "basebmp/compositeiterator.hxx"
25 #include "basebmp/iteratortraits.hxx"
27 #include "basebmp/accessor.hxx"
28 #include "basebmp/accessortraits.hxx"
29 #include "basebmp/accessoradapters.hxx"
30 #include "basebmp/colorblendaccessoradapter.hxx"
32 #include "basebmp/color.hxx"
33 #include "basebmp/colormisc.hxx"
34 #include "basebmp/colortraits.hxx"
36 #include "basebmp/greylevelformats.hxx"
37 #include "basebmp/paletteformats.hxx"
38 #include "basebmp/rgbmaskpixelformats.hxx"
39 #include "basebmp/rgb24pixelformats.hxx"
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"
48 #include "basebmp/tools.hxx"
49 #include "intconversion.hxx"
51 #include <rtl/alloc.h>
52 #include <osl/diagnose.h>
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>
65 #include <vigra/iteratortraits.hxx>
66 #include <vigra/rgbvalue.hxx>
67 #include <vigra/copyimage.hxx>
68 #include <vigra/tuple.hxx>
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 operator^( RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
> const& lhs
,
78 RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
> const& rhs
)
80 RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
> res(
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.
98 Destination bitmap accessor
101 Input accessor, is expected to generate a std::pair as the
105 Either FastMask or NoFastMask, depending on whether the mask
106 is guaranteed to contain only 0s and 1s.
108 template< class DestAccessor
,
109 class JoinedAccessor
,
111 typename MaskFunctorMode
> struct masked_input_splitting_accessor
113 typedef BinarySetterFunctionAccessorAdapter
<
115 BinaryFunctorSplittingWrapper
<
116 typename outputMaskFunctorSelector
<
117 typename
JoinedAccessor::value_type::first_type
,
118 typename
JoinedAccessor::value_type::second_type
,
120 MaskFunctorMode
>::type
> > type
;
125 // Actual BitmapDevice implementation (templatized by accessor and iterator)
126 //--------------------------------------------------------------------------
128 /** Implementation of the BitmapDevice interface
131 Iterator to access bitmap memory
134 Raw accessor, to access pixel values directly
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.
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.
149 template< class DestIterator
,
151 class AccessorSelector
,
152 class Masks
> class BitmapRenderer
:
156 typedef DestIterator dest_iterator_type
;
157 typedef RawAccessor raw_accessor_type
;
158 typedef AccessorSelector accessor_selector
;
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
;
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
;
168 typedef typename
AccessorSelector::template wrap_accessor
<
169 raw_accessor_type
>::type dest_accessor_type
;
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
;
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
;
186 // -------------------------------------------------------
188 typedef AccessorTraits
< raw_accessor_type
> raw_accessor_traits
;
189 typedef typename uInt32Converter
<
190 typename
raw_accessor_type::value_type
>::to to_uint32_functor
;
192 // -------------------------------------------------------
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
;
200 // -------------------------------------------------------
202 typedef typename
raw_accessor_traits::template masked_accessor
<
203 mask_rawaccessor_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
;
214 // -------------------------------------------------------
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
,
223 Masks::clipmask_polarity
>::type raw_maskedmask_accessor_type
;
225 typedef CompositeIterator2D
<
226 composite_iterator_type
,
227 mask_iterator_type
> composite_composite_mask_iterator_type
;
229 // -------------------------------------------------------
231 typedef ConstantColorBlendSetterAccessorAdapter
<
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
,
240 Masks::clipmask_polarity
>::type masked_colorblend_accessor_type
;
242 // -------------------------------------------------------
244 typedef ConstantColorBlendSetterAccessorAdapter
<
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
,
253 Masks::clipmask_polarity
>::type masked_colorblend_generic_accessor_type
;
255 // -------------------------------------------------------
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
;
262 // -------------------------------------------------------
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
;
283 // -------------------------------------------------------
285 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
),
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 maRawMaskedMaskAccessor( rawAccessor
)
319 void damaged( const basegfx::B2IBox
& rDamageRect
) const
322 mpDamage
->damaged( rDamageRect
);
325 void damagedPointSize( const basegfx::B2IPoint
& rPoint
,
326 const basegfx::B2IBox
& rSize
) const
329 basegfx::B2IPoint
aLower( rPoint
.getX() + rSize
.getWidth(),
330 rPoint
.getY() + rSize
.getHeight() );
331 damaged( basegfx::B2IBox( rPoint
, aLower
) );
335 void damagedPixel( const basegfx::B2IPoint
& rDamagePoint
) const
340 sal_Int32
nX(rDamagePoint
.getX());
341 sal_Int32
nY(rDamagePoint
.getY());
342 if (nX
< SAL_MAX_INT32
)
344 if (nY
< SAL_MAX_INT32
)
347 basegfx::B2IPoint
aEnd( nX
, nY
);
348 damaged( basegfx::B2IBox( rDamagePoint
, aEnd
) );
351 boost::shared_ptr
<BitmapRenderer
> getCompatibleBitmap( const BitmapDeviceSharedPtr
& bmp
) const
353 return boost::dynamic_pointer_cast
< BitmapRenderer
>( bmp
);
356 virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr
& bmp
) const
358 // TODO(P1): dynamic_cast usually called twice for
359 // compatible formats
360 return getCompatibleBitmap(bmp
).get() != NULL
;
363 boost::shared_ptr
<mask_bitmap_type
> getCompatibleClipMask( const BitmapDeviceSharedPtr
& bmp
) const
365 boost::shared_ptr
<mask_bitmap_type
> pMask( boost::dynamic_pointer_cast
<mask_bitmap_type
>( bmp
));
370 if( pMask
->getSize() != getSize() )
376 virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr
& bmp
) const
378 // TODO(P1): dynamic_cast usually called twice for
379 // compatible formats
380 return boost::dynamic_pointer_cast
<mask_bitmap_type
>( bmp
).get() != NULL
;
383 boost::shared_ptr
<alphamask_bitmap_type
> getCompatibleAlphaMask( const BitmapDeviceSharedPtr
& bmp
) const
385 return boost::dynamic_pointer_cast
<alphamask_bitmap_type
>( bmp
);
388 virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr
& bmp
) const
390 // TODO(P1): dynamic_cast usually called twice for
391 // compatible formats
392 return getCompatibleAlphaMask( bmp
).get() != NULL
;
395 virtual void clear_i( Color fillColor
,
396 const basegfx::B2IBox
& rBounds
)
398 fillImage(destIterRange(maBegin
,
407 virtual void setPixel_i( const basegfx::B2IPoint
& rPt
,
411 const DestIterator
pixel( maBegin
+
412 vigra::Diff2D(rPt
.getX(),
414 if( drawMode
== DrawMode_XOR
)
415 maXorAccessor
.set( pixelColor
,
418 maAccessor
.set( pixelColor
,
423 virtual void setPixel_i( const basegfx::B2IPoint
& rPt
,
426 const BitmapDeviceSharedPtr
& rClip
)
428 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rClip
) );
431 const vigra::Diff2D
offset(rPt
.getX(),
434 const composite_iterator_type
aIter(
436 pMask
->maBegin
+ offset
);
438 if( drawMode
== DrawMode_XOR
)
439 maMaskedXorAccessor
.set( pixelColor
,
442 maMaskedAccessor
.set( pixelColor
,
447 virtual Color
getPixel_i(const basegfx::B2IPoint
& rPt
)
449 const DestIterator
pixel( maBegin
+
450 vigra::Diff2D(rPt
.getX(),
452 return maAccessor(pixel
);
455 virtual sal_uInt32
getPixelData_i( const basegfx::B2IPoint
& rPt
)
457 const DestIterator
pixel( maBegin
+
458 vigra::Diff2D(rPt
.getX(),
460 return maToUInt32Converter(maRawAccessor(pixel
));
463 template< typename Iterator
, typename Col
, typename RawAcc
>
464 void implRenderLine2( const basegfx::B2IPoint
& rPt1
,
465 const basegfx::B2IPoint
& rPt2
,
466 const basegfx::B2IBox
& rBounds
,
468 const Iterator
& begin
,
469 const RawAcc
& rawAcc
)
471 renderClippedLine( rPt1
,
477 // TODO(P2): perhaps this needs pushing up the stack a bit
478 // to make more complex polygons more efficient ...
479 damaged( basegfx::B2IBox( rPt1
, rPt2
) );
482 template< typename Iterator
, typename Accessor
, typename RawAcc
>
483 void implRenderLine( const basegfx::B2IPoint
& rPt1
,
484 const basegfx::B2IPoint
& rPt2
,
485 const basegfx::B2IBox
& rBounds
,
487 const Iterator
& begin
,
489 const RawAcc
& rawAcc
)
491 implRenderLine2( rPt1
,rPt2
,rBounds
,
498 template< typename Iterator
, typename RawAcc
, typename XorAcc
>
499 void implDrawLine( const basegfx::B2IPoint
& rPt1
,
500 const basegfx::B2IPoint
& rPt2
,
501 const basegfx::B2IBox
& rBounds
,
503 const Iterator
& begin
,
504 const RawAcc
& rawAcc
,
505 const XorAcc
& xorAcc
,
508 if( drawMode
== DrawMode_XOR
)
509 implRenderLine( rPt1
, rPt2
, rBounds
, col
,
510 begin
, maAccessor
, xorAcc
);
512 implRenderLine( rPt1
, rPt2
, rBounds
, col
,
513 begin
, maAccessor
, rawAcc
);
516 virtual void drawLine_i(const basegfx::B2IPoint
& rPt1
,
517 const basegfx::B2IPoint
& rPt2
,
518 const basegfx::B2IBox
& rBounds
,
522 implDrawLine(rPt1
,rPt2
,rBounds
,lineColor
,
524 maRawAccessor
,maRawXorAccessor
,drawMode
);
527 composite_iterator_type
getMaskedIter( const BitmapDeviceSharedPtr
& rClip
) const
529 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rClip
) );
532 return composite_iterator_type( maBegin
,
536 virtual void drawLine_i(const basegfx::B2IPoint
& rPt1
,
537 const basegfx::B2IPoint
& rPt2
,
538 const basegfx::B2IBox
& rBounds
,
541 const BitmapDeviceSharedPtr
& rClip
)
543 implDrawLine(rPt1
,rPt2
,rBounds
,lineColor
,
544 getMaskedIter(rClip
),
546 maRawMaskedXorAccessor
,drawMode
);
549 template< typename Iterator
, typename RawAcc
>
550 void implDrawPolygon( const basegfx::B2DPolygon
& rPoly
,
551 const basegfx::B2IBox
& rBounds
,
553 const Iterator
& begin
,
556 basegfx::B2DPolygon
aPoly( rPoly
);
557 if( rPoly
.areControlPointsUsed() )
558 aPoly
= basegfx::tools::adaptiveSubdivideByCount( rPoly
);
560 const typename
dest_iterator_type::value_type
colorIndex( maColorLookup(
563 const sal_uInt32
nVertices( aPoly
.count() );
564 for( sal_uInt32 i
=1; i
<nVertices
; ++i
)
565 implRenderLine2( basegfx::fround(aPoly
.getB2DPoint(i
-1)),
566 basegfx::fround(aPoly
.getB2DPoint(i
)),
572 if( nVertices
> 1 && aPoly
.isClosed() )
573 implRenderLine2( basegfx::fround(aPoly
.getB2DPoint(nVertices
-1)),
574 basegfx::fround(aPoly
.getB2DPoint(0)),
581 virtual void drawPolygon_i(const basegfx::B2DPolygon
& rPoly
,
582 const basegfx::B2IBox
& rBounds
,
586 if( drawMode
== DrawMode_XOR
)
587 implDrawPolygon( rPoly
, rBounds
, lineColor
,
591 implDrawPolygon( rPoly
, rBounds
, lineColor
,
596 virtual void drawPolygon_i(const basegfx::B2DPolygon
& rPoly
,
597 const basegfx::B2IBox
& rBounds
,
600 const BitmapDeviceSharedPtr
& rClip
)
602 if( drawMode
== DrawMode_XOR
)
603 implDrawPolygon( rPoly
, rBounds
, lineColor
,
604 getMaskedIter(rClip
),
605 maRawMaskedXorAccessor
);
607 implDrawPolygon( rPoly
, rBounds
, lineColor
,
608 getMaskedIter(rClip
),
609 maRawMaskedAccessor
);
612 template< typename Iterator
, typename RawAcc
>
613 void implFillPolyPolygon( const basegfx::B2DPolyPolygon
& rPoly
,
615 const Iterator
& begin
,
617 const basegfx::B2IBox
& rBounds
)
619 basegfx::B2DPolyPolygon
aPoly( rPoly
);
620 if( rPoly
.areControlPointsUsed() )
621 aPoly
= basegfx::tools::adaptiveSubdivideByCount( rPoly
);
623 renderClippedPolyPolygon( begin
,
625 maColorLookup( maAccessor
,
629 basegfx::FillRule_EVEN_ODD
);
633 basegfx::B2DRange
const aPolyBounds( basegfx::tools::getRange(aPoly
) );
634 damaged( basegfx::unotools::b2ISurroundingBoxFromB2DRange( aPolyBounds
) );
638 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon
& rPoly
,
641 const basegfx::B2IBox
& rBounds
)
643 if( drawMode
== DrawMode_XOR
)
644 implFillPolyPolygon( rPoly
, fillColor
,
649 implFillPolyPolygon( rPoly
, fillColor
,
655 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon
& rPoly
,
658 const basegfx::B2IBox
& rBounds
,
659 const BitmapDeviceSharedPtr
& rClip
)
661 if( drawMode
== DrawMode_XOR
)
662 implFillPolyPolygon( rPoly
, fillColor
,
663 getMaskedIter(rClip
),
664 maRawMaskedXorAccessor
,
667 implFillPolyPolygon( rPoly
, fillColor
,
668 getMaskedIter(rClip
),
673 template< typename Iterator
, typename RawAcc
>
674 void implDrawBitmap(const BitmapDeviceSharedPtr
& rSrcBitmap
,
675 const basegfx::B2IBox
& rSrcRect
,
676 const basegfx::B2IBox
& rDstRect
,
677 const Iterator
& begin
,
680 boost::shared_ptr
<BitmapRenderer
> pSrcBmp( getCompatibleBitmap(rSrcBitmap
) );
681 OSL_ASSERT( pSrcBmp
);
684 srcIterRange(pSrcBmp
->maBegin
,
685 pSrcBmp
->maRawAccessor
,
690 rSrcBitmap
.get() == this );
694 template< typename Iterator
, typename Acc
>
695 void implDrawBitmapGeneric(const BitmapDeviceSharedPtr
& rSrcBitmap
,
696 const basegfx::B2IBox
& rSrcRect
,
697 const basegfx::B2IBox
& rDstRect
,
698 const Iterator
& begin
,
701 GenericColorImageAccessor
aSrcAcc( rSrcBitmap
);
704 srcIterRange(vigra::Diff2D(),
713 virtual void drawBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
714 const basegfx::B2IBox
& rSrcRect
,
715 const basegfx::B2IBox
& rDstRect
,
718 if( isCompatibleBitmap( rSrcBitmap
) )
720 if( drawMode
== DrawMode_XOR
)
721 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
725 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
731 if( drawMode
== DrawMode_XOR
)
732 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
736 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
743 virtual void drawBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
744 const basegfx::B2IBox
& rSrcRect
,
745 const basegfx::B2IBox
& rDstRect
,
747 const BitmapDeviceSharedPtr
& rClip
)
749 if( isCompatibleBitmap( rSrcBitmap
) )
751 if( drawMode
== DrawMode_XOR
)
752 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
753 getMaskedIter(rClip
),
754 maRawMaskedXorAccessor
);
756 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
757 getMaskedIter(rClip
),
758 maRawMaskedAccessor
);
762 if( drawMode
== DrawMode_XOR
)
763 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
764 getMaskedIter(rClip
),
765 maMaskedXorAccessor
);
767 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
768 getMaskedIter(rClip
),
774 virtual void drawMaskedColor_i(Color aSrcColor
,
775 const BitmapDeviceSharedPtr
& rAlphaMask
,
776 const basegfx::B2IBox
& rSrcRect
,
777 const basegfx::B2IPoint
& rDstPoint
)
779 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rAlphaMask
) );
780 boost::shared_ptr
<alphamask_bitmap_type
> pAlpha( getCompatibleAlphaMask(rAlphaMask
) );
784 maColorBlendAccessor
.setColor( aSrcColor
);
786 vigra::copyImage( srcIterRange(pAlpha
->maBegin
,
787 pAlpha
->maRawAccessor
,
790 maColorBlendAccessor
,
795 const composite_iterator_type
aBegin(
796 maBegin
+ vigra::Diff2D(rDstPoint
.getX(),
798 pMask
->maBegin
+ topLeft(rSrcRect
) );
801 aBegin
+ vigra::Diff2D(rSrcRect
.getWidth(),
802 rSrcRect
.getHeight()),
810 GenericColorImageAccessor
aSrcAcc( rAlphaMask
);
811 maGenericColorBlendAccessor
.setColor( aSrcColor
);
813 vigra::copyImage( srcIterRange(vigra::Diff2D(),
817 maGenericColorBlendAccessor
,
820 damagedPointSize( rDstPoint
, rSrcRect
);
823 virtual void drawMaskedColor_i(Color aSrcColor
,
824 const BitmapDeviceSharedPtr
& rAlphaMask
,
825 const basegfx::B2IBox
& rSrcRect
,
826 const basegfx::B2IPoint
& rDstPoint
,
827 const BitmapDeviceSharedPtr
& rClip
)
829 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rAlphaMask
) );
830 boost::shared_ptr
<alphamask_bitmap_type
> pAlpha( getCompatibleAlphaMask(rAlphaMask
) );
834 const composite_iterator_type
aBegin( getMaskedIter(rClip
) );
835 maMaskedColorBlendAccessor
.get1stWrappedAccessor().setColor(
838 vigra::copyImage( srcIterRange(pAlpha
->maBegin
,
839 pAlpha
->maRawAccessor
,
842 maMaskedColorBlendAccessor
,
847 boost::shared_ptr
<mask_bitmap_type
> pClipMask( getCompatibleClipMask(rClip
) );
848 OSL_ASSERT( pClipMask
);
850 // setup a ((iter,mask),clipMask) composite composite
851 // iterator, to pass both masks (clip and alpha mask)
853 const composite_composite_mask_iterator_type
aBegin(
854 composite_iterator_type(
855 maBegin
+ vigra::Diff2D(rDstPoint
.getX(),
857 pMask
->maBegin
+ topLeft(rSrcRect
)),
858 pClipMask
->maBegin
+ vigra::Diff2D(rDstPoint
.getX(),
862 aBegin
+ vigra::Diff2D(rSrcRect
.getWidth(),
863 rSrcRect
.getHeight()),
864 maRawMaskedMaskAccessor
,
871 GenericColorImageAccessor
aSrcAcc( rAlphaMask
);
872 const composite_iterator_type
aBegin( getMaskedIter(rClip
) );
873 maGenericMaskedColorBlendAccessor
.get1stWrappedAccessor().setColor(
876 vigra::copyImage( srcIterRange(vigra::Diff2D(),
880 maGenericMaskedColorBlendAccessor
,
883 damagedPointSize( rDstPoint
, rSrcRect
);
886 template< typename Iterator
, typename Acc
>
887 void implDrawMaskedBitmap(const BitmapDeviceSharedPtr
& rSrcBitmap
,
888 const BitmapDeviceSharedPtr
& rMask
,
889 const basegfx::B2IBox
& rSrcRect
,
890 const basegfx::B2IBox
& rDstRect
,
891 const Iterator
& begin
,
894 boost::shared_ptr
<BitmapRenderer
> pSrcBmp( getCompatibleBitmap(rSrcBitmap
) );
895 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rMask
) );
896 OSL_ASSERT( pMask
&& pSrcBmp
);
899 srcIterRange(composite_iterator_type(
902 joined_image_accessor_type(
904 pMask
->maRawAccessor
),
907 typename masked_input_splitting_accessor
<
909 joined_image_accessor_type
,
910 Masks::clipmask_polarity
,
911 FastMask
>::type(acc
),
913 rSrcBitmap
.get() == this);
917 template< typename Iterator
, typename Acc
>
918 void implDrawMaskedBitmapGeneric(const BitmapDeviceSharedPtr
& rSrcBitmap
,
919 const BitmapDeviceSharedPtr
& rMask
,
920 const basegfx::B2IBox
& rSrcRect
,
921 const basegfx::B2IBox
& rDstRect
,
922 const Iterator
& begin
,
925 GenericColorImageAccessor
aSrcAcc( rSrcBitmap
);
926 GenericColorImageAccessor
aMaskAcc( rMask
);
928 const vigra::Diff2D
aTopLeft(rSrcRect
.getMinX(),
930 const vigra::Diff2D
aBottomRight(rSrcRect
.getMaxX(),
934 generic_composite_iterator_type(
936 generic_composite_iterator_type(
937 aBottomRight
,aBottomRight
),
938 joined_generic_image_accessor_type(
942 typename masked_input_splitting_accessor
<
944 joined_generic_image_accessor_type
,
945 Masks::clipmask_polarity
,
946 NoFastMask
>::type(acc
),
951 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
952 const BitmapDeviceSharedPtr
& rMask
,
953 const basegfx::B2IBox
& rSrcRect
,
954 const basegfx::B2IBox
& rDstRect
,
957 if( isCompatibleClipMask(rMask
) &&
958 isCompatibleBitmap(rSrcBitmap
) )
960 if( drawMode
== DrawMode_XOR
)
961 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
966 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
973 if( drawMode
== DrawMode_XOR
)
974 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
979 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
987 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
988 const BitmapDeviceSharedPtr
& rMask
,
989 const basegfx::B2IBox
& rSrcRect
,
990 const basegfx::B2IBox
& rDstRect
,
992 const BitmapDeviceSharedPtr
& rClip
)
994 if( isCompatibleClipMask(rMask
) &&
995 isCompatibleBitmap(rSrcBitmap
) )
997 if( drawMode
== DrawMode_XOR
)
998 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1000 getMaskedIter(rClip
),
1001 maMaskedXorAccessor
);
1003 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1005 getMaskedIter(rClip
),
1010 if( drawMode
== DrawMode_XOR
)
1011 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1013 getMaskedIter(rClip
),
1014 maMaskedXorAccessor
);
1016 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1018 getMaskedIter(rClip
),
1021 damaged( rDstRect
);
1024 IBitmapDeviceDamageTrackerSharedPtr
getDamageTracker_i() const
1028 void setDamageTracker_i( const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
)
1035 struct ImplBitmapDevice
1037 /** Bitmap memory plus deleter.
1039 Always points to the start of the mem
1041 RawMemorySharedArray mpMem
;
1043 /// Palette memory plus deleter (might be NULL)
1044 PaletteMemorySharedVector mpPalette
;
1046 /** Bounds of the device.
1048 maBounds.getWidth()/getHeight() yield the true size of the
1049 device (i.e. the rectangle given by maBounds covers the device
1050 area under the including-the-bottommost-and-rightmost-pixels
1053 basegfx::B2IBox maBounds
;
1055 //// Size of the actual frame buffer
1056 basegfx::B2IVector maBufferSize
;
1058 /// Scanline format, as provided at the constructor
1059 sal_Int32 mnScanlineFormat
;
1061 /// Scanline stride. Negative for bottom-to-top formats
1062 sal_Int32 mnScanlineStride
;
1064 /// raw ptr to 0th scanline. used for cloning a generic renderer
1065 sal_uInt8
* mpFirstScanline
;
1067 /** (Optional) device sharing the same memory, and used for input
1068 clip masks/alpha masks/bitmaps that don't match our exact
1071 This is to avoid the combinatorical explosion when dealing
1072 with n bitmap formats, which could be combined with n clip
1073 masks, alpha masks and bitmap masks (yielding a total of n^4
1074 combinations). Since each BitmapRenderer is specialized for
1075 one specific combination of said formats, a lot of duplicate
1076 code would be generated, most of which probably never
1077 used. Therefore, only the most common combinations are
1078 specialized templates, the remainder gets handled by this
1079 generic renderer (via runtime polymorphism).
1081 BitmapDeviceSharedPtr mpGenericRenderer
;
1085 BitmapDevice::BitmapDevice( const basegfx::B2IBox
& rBounds
,
1086 const basegfx::B2IVector
& rBufferSize
,
1087 sal_Int32 nScanlineFormat
,
1088 sal_Int32 nScanlineStride
,
1089 sal_uInt8
* pFirstScanline
,
1090 const RawMemorySharedArray
& rMem
,
1091 const PaletteMemorySharedVector
& rPalette
) :
1092 mpImpl( new ImplBitmapDevice
)
1094 mpImpl
->mpMem
= rMem
;
1095 mpImpl
->mpPalette
= rPalette
;
1096 mpImpl
->maBounds
= rBounds
;
1097 mpImpl
->maBufferSize
= rBufferSize
;
1098 mpImpl
->mnScanlineFormat
= nScanlineFormat
;
1099 mpImpl
->mnScanlineStride
= nScanlineStride
;
1100 mpImpl
->mpFirstScanline
= pFirstScanline
;
1103 BitmapDevice::~BitmapDevice()
1105 // outline, because of internal ImplBitmapDevice
1106 SAL_INFO( "basebmp.bitmapdevice", "~BitmapDevice(" << this << ")" );
1109 basegfx::B2IVector
BitmapDevice::getSize() const
1111 return basegfx::B2IVector(
1112 mpImpl
->maBounds
.getMaxX() - mpImpl
->maBounds
.getMinX(),
1113 mpImpl
->maBounds
.getMaxY() - mpImpl
->maBounds
.getMinY() );
1116 bool BitmapDevice::isTopDown() const
1118 return mpImpl
->mnScanlineStride
>= 0;
1121 basegfx::B2IVector
BitmapDevice::getBufferSize() const
1123 return mpImpl
->maBufferSize
;
1126 sal_Int32
BitmapDevice::getScanlineFormat() const
1128 return mpImpl
->mnScanlineFormat
;
1131 sal_Int32
BitmapDevice::getScanlineStride() const
1133 return mpImpl
->mnScanlineStride
< 0 ?
1134 -mpImpl
->mnScanlineStride
: mpImpl
->mnScanlineStride
;
1137 RawMemorySharedArray
BitmapDevice::getBuffer() const
1139 return mpImpl
->mpMem
;
1142 IBitmapDeviceDamageTrackerSharedPtr
BitmapDevice::getDamageTracker() const
1144 return getDamageTracker_i();
1147 void BitmapDevice::setDamageTracker( const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
)
1149 setDamageTracker_i(rDamage
);
1152 PaletteMemorySharedVector
BitmapDevice::getPalette() const
1154 return mpImpl
->mpPalette
;
1157 void BitmapDevice::clear( Color fillColor
)
1159 clear_i( fillColor
, mpImpl
->maBounds
);
1162 void BitmapDevice::setPixel( const basegfx::B2IPoint
& rPt
,
1166 if( mpImpl
->maBounds
.isInside(rPt
) )
1167 setPixel_i(rPt
,lineColor
,drawMode
);
1170 void BitmapDevice::setPixel( const basegfx::B2IPoint
& rPt
,
1173 const BitmapDeviceSharedPtr
& rClip
)
1177 setPixel(rPt
,lineColor
,drawMode
);
1181 if( mpImpl
->maBounds
.isInside(rPt
) )
1183 if( isCompatibleClipMask( rClip
) )
1184 setPixel_i(rPt
,lineColor
,drawMode
,rClip
);
1186 getGenericRenderer()->setPixel( rPt
, lineColor
, drawMode
, rClip
);
1190 Color
BitmapDevice::getPixel( const basegfx::B2IPoint
& rPt
)
1192 if( mpImpl
->maBounds
.isInside(rPt
) )
1193 return getPixel_i(rPt
);
1198 sal_uInt32
BitmapDevice::getPixelData( const basegfx::B2IPoint
& rPt
)
1200 if( mpImpl
->maBounds
.isInside(rPt
) )
1201 return getPixelData_i(rPt
);
1206 void BitmapDevice::drawLine( const basegfx::B2IPoint
& rPt1
,
1207 const basegfx::B2IPoint
& rPt2
,
1218 void BitmapDevice::drawLine( const basegfx::B2IPoint
& rPt1
,
1219 const basegfx::B2IPoint
& rPt2
,
1222 const BitmapDeviceSharedPtr
& rClip
)
1226 drawLine(rPt1
,rPt2
,lineColor
,drawMode
);
1230 if( isCompatibleClipMask( rClip
) )
1238 getGenericRenderer()->drawLine( rPt1
, rPt2
, lineColor
,
1242 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon
& rPoly
,
1246 const sal_uInt32
numVertices( rPoly
.count() );
1248 drawPolygon_i( rPoly
,
1250 lineColor
, drawMode
);
1253 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon
& rPoly
,
1256 const BitmapDeviceSharedPtr
& rClip
)
1260 drawPolygon(rPoly
,lineColor
,drawMode
);
1264 const sal_uInt32
numVertices( rPoly
.count() );
1267 if( isCompatibleClipMask( rClip
) )
1268 drawPolygon_i( rPoly
,
1270 lineColor
, drawMode
, rClip
);
1272 getGenericRenderer()->drawPolygon( rPoly
, lineColor
,
1277 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon
& rPoly
,
1281 fillPolyPolygon_i( rPoly
, fillColor
, drawMode
, mpImpl
->maBounds
);
1284 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon
& rPoly
,
1287 const BitmapDeviceSharedPtr
& rClip
)
1291 fillPolyPolygon(rPoly
,fillColor
,drawMode
);
1295 if( isCompatibleClipMask( rClip
) )
1296 fillPolyPolygon_i( rPoly
, fillColor
, drawMode
, mpImpl
->maBounds
, rClip
);
1298 getGenericRenderer()->fillPolyPolygon( rPoly
, fillColor
,
1305 void assertImagePoint( const basegfx::B2IPoint
& rPt
,
1306 const basegfx::B2IBox
& rPermittedRange
)
1308 (void)rPt
; (void)rPermittedRange
;
1309 OSL_ASSERT( rPermittedRange
.isInside(rPt
) );
1312 void assertImageRange( const basegfx::B2IBox
& rRange
,
1313 const basegfx::B2IBox
& rPermittedRange
)
1315 #if OSL_DEBUG_LEVEL > 0
1316 basegfx::B2IBox
aRange( rRange
);
1317 aRange
.intersect( rPermittedRange
);
1319 OSL_ASSERT( aRange
== rRange
);
1321 (void)rRange
; (void)rPermittedRange
;
1325 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1326 // to basegfx, and use here!
1327 bool clipAreaImpl( ::basegfx::B2IBox
& io_rSourceArea
,
1328 ::basegfx::B2IPoint
& io_rDestPoint
,
1329 const ::basegfx::B2IBox
& rSourceBounds
,
1330 const ::basegfx::B2IBox
& rDestBounds
)
1332 const ::basegfx::B2IPoint
aSourceTopLeft(
1333 io_rSourceArea
.getMinimum() );
1335 ::basegfx::B2IBox
aLocalSourceArea( io_rSourceArea
);
1337 // clip source area (which must be inside rSourceBounds)
1338 aLocalSourceArea
.intersect( rSourceBounds
);
1340 if( aLocalSourceArea
.isEmpty() )
1343 // calc relative new source area points (relative to orig
1345 const ::basegfx::B2IVector
aUpperLeftOffset(
1346 aLocalSourceArea
.getMinimum()-aSourceTopLeft
);
1347 const ::basegfx::B2IVector
aLowerRightOffset(
1348 aLocalSourceArea
.getMaximum()-aSourceTopLeft
);
1350 ::basegfx::B2IBox
aLocalDestArea( io_rDestPoint
+ aUpperLeftOffset
,
1351 io_rDestPoint
+ aLowerRightOffset
);
1353 // clip dest area (which must be inside rDestBounds)
1354 aLocalDestArea
.intersect( rDestBounds
);
1356 if( aLocalDestArea
.isEmpty() )
1359 // calc relative new dest area points (relative to orig
1361 const ::basegfx::B2IVector
aDestUpperLeftOffset(
1362 aLocalDestArea
.getMinimum()-io_rDestPoint
);
1363 const ::basegfx::B2IVector
aDestLowerRightOffset(
1364 aLocalDestArea
.getMaximum()-io_rDestPoint
);
1366 io_rSourceArea
= ::basegfx::B2IBox( aSourceTopLeft
+ aDestUpperLeftOffset
,
1367 aSourceTopLeft
+ aDestLowerRightOffset
);
1368 io_rDestPoint
= aLocalDestArea
.getMinimum();
1373 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1374 // to basegfx, and use here!
1375 bool clipAreaImpl( ::basegfx::B2IBox
& io_rDestArea
,
1376 ::basegfx::B2IBox
& io_rSourceArea
,
1377 const ::basegfx::B2IBox
& rDestBounds
,
1378 const ::basegfx::B2IBox
& rSourceBounds
)
1380 // extract inherent scale
1381 const double nScaleX( io_rDestArea
.getWidth() / (double)io_rSourceArea
.getWidth() );
1382 const double nScaleY( io_rDestArea
.getHeight() / (double)io_rSourceArea
.getHeight() );
1384 // extract range origins
1385 const basegfx::B2IPoint
aDestTopLeft(
1386 io_rDestArea
.getMinimum() );
1387 const ::basegfx::B2IPoint
aSourceTopLeft(
1388 io_rSourceArea
.getMinimum() );
1390 ::basegfx::B2IBox
aLocalSourceArea( io_rSourceArea
);
1392 // clip source area (which must be inside rSourceBounds)
1393 aLocalSourceArea
.intersect( rSourceBounds
);
1395 if( aLocalSourceArea
.isEmpty() )
1398 // calc relative new source area points (relative to orig
1400 const ::basegfx::B2IVector
aUpperLeftOffset(
1401 aLocalSourceArea
.getMinimum()-aSourceTopLeft
);
1402 const ::basegfx::B2IVector
aLowerRightOffset(
1403 aLocalSourceArea
.getMaximum()-aSourceTopLeft
);
1405 ::basegfx::B2IBox
aLocalDestArea( basegfx::fround(aDestTopLeft
.getX() + nScaleX
*aUpperLeftOffset
.getX()),
1406 basegfx::fround(aDestTopLeft
.getY() + nScaleY
*aUpperLeftOffset
.getY()),
1407 basegfx::fround(aDestTopLeft
.getX() + nScaleX
*aLowerRightOffset
.getX()),
1408 basegfx::fround(aDestTopLeft
.getY() + nScaleY
*aLowerRightOffset
.getY()) );
1410 // clip dest area (which must be inside rDestBounds)
1411 aLocalDestArea
.intersect( rDestBounds
);
1413 if( aLocalDestArea
.isEmpty() )
1416 // calc relative new dest area points (relative to orig
1418 const ::basegfx::B2IVector
aDestUpperLeftOffset(
1419 aLocalDestArea
.getMinimum()-aDestTopLeft
);
1420 const ::basegfx::B2IVector
aDestLowerRightOffset(
1421 aLocalDestArea
.getMaximum()-aDestTopLeft
);
1423 io_rSourceArea
= ::basegfx::B2IBox( basegfx::fround(aSourceTopLeft
.getX() + aDestUpperLeftOffset
.getX()/nScaleX
),
1424 basegfx::fround(aSourceTopLeft
.getY() + aDestUpperLeftOffset
.getY()/nScaleY
),
1425 basegfx::fround(aSourceTopLeft
.getX() + aDestLowerRightOffset
.getX()/nScaleX
),
1426 basegfx::fround(aSourceTopLeft
.getY() + aDestLowerRightOffset
.getY()/nScaleY
) );
1427 io_rDestArea
= aLocalDestArea
;
1429 // final source area clip (chopping round-offs)
1430 io_rSourceArea
.intersect( rSourceBounds
);
1432 if( io_rSourceArea
.isEmpty() )
1440 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1441 const basegfx::B2IBox
& rSrcRect
,
1442 const basegfx::B2IBox
& rDstRect
,
1445 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1446 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1447 basegfx::B2IBox
aSrcRange( rSrcRect
);
1448 basegfx::B2IBox
aDestRange( rDstRect
);
1450 if( clipAreaImpl( aDestRange
,
1455 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1456 assertImageRange(aSrcRange
,aSrcBounds
);
1458 drawBitmap_i( rSrcBitmap
, aSrcRange
, aDestRange
, drawMode
);
1462 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1463 const basegfx::B2IBox
& rSrcRect
,
1464 const basegfx::B2IBox
& rDstRect
,
1466 const BitmapDeviceSharedPtr
& rClip
)
1470 drawBitmap(rSrcBitmap
,rSrcRect
,rDstRect
,drawMode
);
1474 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1475 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1476 basegfx::B2IBox
aSrcRange( rSrcRect
);
1477 basegfx::B2IBox
aDestRange( rDstRect
);
1479 if( clipAreaImpl( aDestRange
,
1484 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1485 assertImageRange(aSrcRange
,aSrcBounds
);
1487 if( isCompatibleClipMask( rClip
) )
1489 drawBitmap_i( rSrcBitmap
, aSrcRange
, aDestRange
, drawMode
, rClip
);
1493 getGenericRenderer()->drawBitmap( rSrcBitmap
, rSrcRect
,
1494 rDstRect
, drawMode
, rClip
);
1499 void BitmapDevice::drawMaskedColor( Color aSrcColor
,
1500 const BitmapDeviceSharedPtr
& rAlphaMask
,
1501 const basegfx::B2IBox
& rSrcRect
,
1502 const basegfx::B2IPoint
& rDstPoint
)
1504 const basegfx::B2IVector
& rSrcSize( rAlphaMask
->getSize() );
1505 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1506 basegfx::B2IBox
aSrcRange( rSrcRect
);
1507 basegfx::B2IPoint
aDestPoint( rDstPoint
);
1509 if( clipAreaImpl( aSrcRange
,
1514 assertImagePoint(aDestPoint
,mpImpl
->maBounds
);
1515 assertImageRange(aSrcRange
,aSrcBounds
);
1517 if( rAlphaMask
.get() == this )
1519 // src == dest, copy rAlphaMask beforehand
1520 // ---------------------------------------------------
1522 const basegfx::B2ITuple
aSize( aSrcRange
.getWidth(),
1523 aSrcRange
.getHeight() );
1524 BitmapDeviceSharedPtr
pAlphaCopy(
1525 cloneBitmapDevice( aSize
,
1526 shared_from_this()) );
1527 basegfx::B2ITuple aGcc3WorkaroundTemporary
;
1528 const basegfx::B2IBox
aAlphaRange( aGcc3WorkaroundTemporary
,
1530 pAlphaCopy
->drawBitmap(rAlphaMask
,
1534 drawMaskedColor_i( aSrcColor
, pAlphaCopy
, aAlphaRange
, aDestPoint
);
1538 drawMaskedColor_i( aSrcColor
, rAlphaMask
, aSrcRange
, aDestPoint
);
1543 void BitmapDevice::drawMaskedColor( Color aSrcColor
,
1544 const BitmapDeviceSharedPtr
& rAlphaMask
,
1545 const basegfx::B2IBox
& rSrcRect
,
1546 const basegfx::B2IPoint
& rDstPoint
,
1547 const BitmapDeviceSharedPtr
& rClip
)
1551 drawMaskedColor(aSrcColor
,rAlphaMask
,rSrcRect
,rDstPoint
);
1555 const basegfx::B2IVector
& rSrcSize( rAlphaMask
->getSize() );
1556 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1557 basegfx::B2IBox
aSrcRange( rSrcRect
);
1558 basegfx::B2IPoint
aDestPoint( rDstPoint
);
1560 if( clipAreaImpl( aSrcRange
,
1565 assertImagePoint(aDestPoint
,mpImpl
->maBounds
);
1566 assertImageRange(aSrcRange
,aSrcBounds
);
1568 if( isCompatibleClipMask( rClip
) )
1570 if( rAlphaMask
.get() == this )
1572 // src == dest, copy rAlphaMask beforehand
1573 // ---------------------------------------------------
1575 const basegfx::B2ITuple
aSize( aSrcRange
.getWidth(),
1576 aSrcRange
.getHeight() );
1577 BitmapDeviceSharedPtr
pAlphaCopy(
1578 cloneBitmapDevice( aSize
,
1579 shared_from_this()) );
1580 basegfx::B2ITuple aGcc3WorkaroundTemporary
;
1581 const basegfx::B2IBox
aAlphaRange( aGcc3WorkaroundTemporary
,
1583 pAlphaCopy
->drawBitmap(rAlphaMask
,
1587 drawMaskedColor_i( aSrcColor
, pAlphaCopy
, aAlphaRange
, aDestPoint
, rClip
);
1591 drawMaskedColor_i( aSrcColor
, rAlphaMask
, aSrcRange
, aDestPoint
, rClip
);
1596 getGenericRenderer()->drawMaskedColor( aSrcColor
, rAlphaMask
,
1597 rSrcRect
, rDstPoint
, rClip
);
1602 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1603 const BitmapDeviceSharedPtr
& rMask
,
1604 const basegfx::B2IBox
& rSrcRect
,
1605 const basegfx::B2IBox
& rDstRect
,
1608 OSL_ASSERT( rMask
->getSize() == rSrcBitmap
->getSize() );
1610 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1611 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1612 basegfx::B2IBox
aSrcRange( rSrcRect
);
1613 basegfx::B2IBox
aDestRange( rDstRect
);
1615 if( clipAreaImpl( aDestRange
,
1620 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1621 assertImageRange(aSrcRange
,aSrcBounds
);
1623 drawMaskedBitmap_i( rSrcBitmap
, rMask
, aSrcRange
, aDestRange
, drawMode
);
1627 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1628 const BitmapDeviceSharedPtr
& rMask
,
1629 const basegfx::B2IBox
& rSrcRect
,
1630 const basegfx::B2IBox
& rDstRect
,
1632 const BitmapDeviceSharedPtr
& rClip
)
1636 drawMaskedBitmap(rSrcBitmap
,rMask
,rSrcRect
,rDstRect
,drawMode
);
1640 OSL_ASSERT( rMask
->getSize() == rSrcBitmap
->getSize() );
1642 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1643 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1644 basegfx::B2IBox
aSrcRange( rSrcRect
);
1645 basegfx::B2IBox
aDestRange( rDstRect
);
1647 if( clipAreaImpl( aDestRange
,
1652 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1653 assertImageRange(aSrcRange
,aSrcBounds
);
1655 if( isCompatibleClipMask( rClip
) )
1657 drawMaskedBitmap_i( rSrcBitmap
, rMask
, aSrcRange
, aDestRange
, drawMode
, rClip
);
1661 getGenericRenderer()->drawMaskedBitmap( rSrcBitmap
, rMask
, rSrcRect
,
1662 rDstRect
, drawMode
, rClip
);
1668 //----------------------------------------------------------------------------------
1670 /** Standard clip and alpha masks
1674 typedef PixelFormatTraits_GREY1_MSB clipmask_format_traits
;
1675 typedef PixelFormatTraits_GREY8 alphamask_format_traits
;
1677 /// Clipmask: 0 means opaque
1678 static const bool clipmask_polarity
= false;
1680 /// Alpha mask: 0 means fully transparent
1681 static const bool alphamask_polarity
= true;
1684 //----------------------------------------------------------------------------------
1686 // Some compilers don't like the nested template wrap_accessor
1687 // reference in the parameter list - being slightly less type safe,
1689 #ifndef BASEBMP_NO_NESTED_TEMPLATE_PARAMETER
1691 /// Produces a specialized renderer for the given pixel format
1692 template< class FormatTraits
, class MaskTraits
>
1693 BitmapDeviceSharedPtr
createRenderer(
1694 const basegfx::B2IBox
& rBounds
,
1695 const basegfx::B2IVector
& rBufferSize
,
1696 sal_Int32 nScanlineFormat
,
1697 sal_Int32 nScanlineStride
,
1698 sal_uInt8
* pFirstScanline
,
1699 typename
FormatTraits::raw_accessor_type
const& rRawAccessor
,
1700 typename
FormatTraits::accessor_selector::template wrap_accessor
<
1701 typename
FormatTraits::raw_accessor_type
>::type
const& rAccessor
,
1702 boost::shared_array
< sal_uInt8
> pMem
,
1703 const PaletteMemorySharedVector
& pPal
,
1704 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1707 template< class FormatTraits
, class MaskTraits
, class Accessor
>
1708 BitmapDeviceSharedPtr
createRenderer(
1709 const basegfx::B2IBox
& rBounds
,
1710 const basegfx::B2IVector
& rBufferSize
,
1711 sal_Int32 nScanlineFormat
,
1712 sal_Int32 nScanlineStride
,
1713 sal_uInt8
* pFirstScanline
,
1714 typename
FormatTraits::raw_accessor_type
const& rRawAccessor
,
1715 Accessor
const& rAccessor
,
1716 boost::shared_array
< sal_uInt8
> pMem
,
1717 const PaletteMemorySharedVector
& pPal
,
1718 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1722 typedef typename
FormatTraits::iterator_type Iterator
;
1723 typedef BitmapRenderer
< Iterator
,
1724 typename
FormatTraits::raw_accessor_type
,
1725 typename
FormatTraits::accessor_selector
,
1726 MaskTraits
> Renderer
;
1728 return BitmapDeviceSharedPtr(
1729 new Renderer( rBounds
,
1735 reinterpret_cast<typename
Iterator::value_type
*>(
1745 /// Create standard grey level palette
1746 PaletteMemorySharedVector
createStandardPalette(
1747 const PaletteMemorySharedVector
& pPal
,
1748 sal_Int32 nNumEntries
)
1750 if( pPal
|| nNumEntries
<= 0 )
1753 boost::shared_ptr
< std::vector
<Color
> > pLocalPal(
1754 new std::vector
<Color
>(nNumEntries
) );
1756 const sal_Int32
nIncrement( 0x00FFFFFF/nNumEntries
);
1758 for( sal_Int32 i
=0, c
=0; i
<nNumEntries
; ++i
,c
+=nIncrement
)
1759 pLocalPal
->at(i
) = Color(0xFF000000 | c
);
1761 pLocalPal
->at(nNumEntries
) = Color(0xFFFFFFFF);
1766 template< class FormatTraits
, class MaskTraits
>
1767 BitmapDeviceSharedPtr
createRenderer(
1768 const basegfx::B2IBox
& rBounds
,
1769 const basegfx::B2IVector
& rBufferSize
,
1770 sal_Int32 nScanlineFormat
,
1771 sal_Int32 nScanlineStride
,
1772 sal_uInt8
* pFirstScanline
,
1773 boost::shared_array
< sal_uInt8
> pMem
,
1774 const PaletteMemorySharedVector
& pPal
,
1775 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1777 return createRenderer
<FormatTraits
,
1778 MaskTraits
>(rBounds
,
1783 typename
FormatTraits::raw_accessor_type(),
1784 typename
FormatTraits::accessor_selector::template
1786 typename
FormatTraits::raw_accessor_type
>::type(),
1792 template< class FormatTraits
, class MaskTraits
>
1793 BitmapDeviceSharedPtr
createRenderer(
1794 const basegfx::B2IBox
& rBounds
,
1795 const basegfx::B2IVector
& rBufferSize
,
1796 sal_Int32 nScanlineFormat
,
1797 sal_Int32 nScanlineStride
,
1798 sal_uInt8
* pFirstScanline
,
1799 boost::shared_array
< sal_uInt8
> pMem
,
1800 PaletteMemorySharedVector pPal
,
1802 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1804 pPal
= createStandardPalette(pPal
,
1805 1UL << nBitsPerPixel
);
1808 return createRenderer
<FormatTraits
,
1809 MaskTraits
>(rBounds
,
1814 typename
FormatTraits::raw_accessor_type(),
1815 typename
FormatTraits::accessor_selector::template
1817 typename
FormatTraits::raw_accessor_type
>::type(
1825 //----------------------------------------------------------------------------------
1827 // TODO(Q3): consolidate with canvas/canvastools.hxx! Best move this
1828 // to o3tl or sal/bithacks.hxx ...
1830 /** Compute the next highest power of 2 of a 32-bit value
1832 Code devised by Sean Anderson, in good ole HAKMEM
1835 @return 1 << (lg(x - 1) + 1)
1837 inline sal_uInt32
nextPow2( sal_uInt32 x
)
1849 //----------------------------------------------------------------------------------
1853 BitmapDeviceSharedPtr
createBitmapDeviceImplInner( const basegfx::B2IVector
& rSize
,
1855 sal_Int32 nScanlineFormat
,
1856 boost::shared_array
< sal_uInt8
> pMem
,
1857 PaletteMemorySharedVector pPal
,
1858 const basegfx::B2IBox
* pSubset
,
1859 const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
)
1861 OSL_ASSERT(rSize
.getX() > 0 && rSize
.getY() > 0);
1863 if( nScanlineFormat
<= Format::NONE
||
1864 nScanlineFormat
> Format::MAX
)
1865 return BitmapDeviceSharedPtr();
1867 static const sal_uInt8 bitsPerPixel
[] =
1870 1, // ONE_BIT_MSB_GREY
1871 1, // ONE_BIT_LSB_GREY
1872 1, // ONE_BIT_MSB_PAL
1873 1, // ONE_BIT_LSB_PAL
1874 4, // FOUR_BIT_MSB_GREY
1875 4, // FOUR_BIT_LSB_GREY
1876 4, // FOUR_BIT_MSB_PAL
1877 4, // FOUR_BIT_LSB_PAL
1879 8, // EIGHT_BIT_GREY
1880 16, // SIXTEEN_BIT_LSB_TC_MASK
1881 16, // SIXTEEN_BIT_MSB_TC_MASK
1882 24, // TWENTYFOUR_BIT_TC_MASK
1883 32, // THIRTYTWO_BIT_TC_MASK_BGRA
1884 32, // THIRTYTWO_BIT_TC_MASK_ARGB
1885 32, // THIRTYTWO_BIT_TC_MASK_ABGR
1886 32, // THIRTYTWO_BIT_TC_MASK_RGBA
1889 sal_Int32
nScanlineStride(0);
1891 // round up to full 8 bit, divide by 8
1892 nScanlineStride
= (rSize
.getX()*bitsPerPixel
[nScanlineFormat
] + 7) >> 3;
1894 // rounded up to next full power-of-two number of bytes
1895 const sal_uInt32 bytesPerPixel
= nextPow2(
1896 (bitsPerPixel
[nScanlineFormat
] + 7) >> 3);
1898 // now make nScanlineStride a multiple of bytesPerPixel
1899 nScanlineStride
= (nScanlineStride
+ bytesPerPixel
- 1) / bytesPerPixel
* bytesPerPixel
;
1901 // factor in bottom-up scanline order case
1902 nScanlineStride
*= bTopDown
? 1 : -1;
1904 const sal_uInt32
nWidth(nScanlineStride
< 0 ? -nScanlineStride
: nScanlineStride
);
1905 const sal_uInt32
nHeight(rSize
.getY());
1907 if (nHeight
&& nWidth
&& nWidth
> SAL_MAX_INT32
/ nHeight
)
1909 SAL_WARN( "basebmp", "suspicious massive alloc " << nWidth
<< " * " << nHeight
);
1910 return BitmapDeviceSharedPtr();
1913 const std::size_t nMemSize(nWidth
* nHeight
);
1918 reinterpret_cast<sal_uInt8
*>(rtl_allocateMemory( nMemSize
)),
1920 if (pMem
.get() == 0 && nMemSize
!= 0)
1921 return BitmapDeviceSharedPtr();
1922 memset(pMem
.get(), 0, nMemSize
);
1925 sal_uInt8
* pFirstScanline
= nScanlineStride
< 0 ?
1926 pMem
.get() + nMemSize
+ nScanlineStride
: pMem
.get();
1928 // shrink render area to given subset, if given
1929 basegfx::B2IBox
aBounds(0,0,rSize
.getX(),rSize
.getY());
1931 aBounds
.intersect( *pSubset
);
1933 switch( nScanlineFormat
)
1935 // ----------------------------------------------------------------------
1938 case Format::ONE_BIT_MSB_GREY
:
1939 return createRenderer
<PixelFormatTraits_GREY1_MSB
,StdMasks
>(
1940 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1941 pFirstScanline
, pMem
, pPal
, rDamage
);
1943 case Format::ONE_BIT_LSB_GREY
:
1944 return createRenderer
<PixelFormatTraits_GREY1_LSB
,StdMasks
>(
1945 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1946 pFirstScanline
, pMem
, pPal
, rDamage
);
1948 case Format::ONE_BIT_MSB_PAL
:
1949 return createRenderer
<PixelFormatTraits_PAL1_MSB
,StdMasks
>(
1950 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1951 pFirstScanline
, pMem
, pPal
,
1952 bitsPerPixel
[nScanlineFormat
], rDamage
);
1954 case Format::ONE_BIT_LSB_PAL
:
1955 return createRenderer
<PixelFormatTraits_PAL1_LSB
,StdMasks
>(
1956 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1957 pFirstScanline
, pMem
, pPal
,
1958 bitsPerPixel
[nScanlineFormat
], rDamage
);
1961 // ----------------------------------------------------------------------
1964 case Format::FOUR_BIT_MSB_GREY
:
1965 return createRenderer
<PixelFormatTraits_GREY4_MSB
,StdMasks
>(
1966 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1967 pFirstScanline
, pMem
, pPal
, rDamage
);
1969 case Format::FOUR_BIT_LSB_GREY
:
1970 return createRenderer
<PixelFormatTraits_GREY4_LSB
,StdMasks
>(
1971 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1972 pFirstScanline
, pMem
, pPal
, rDamage
);
1974 case Format::FOUR_BIT_MSB_PAL
:
1975 return createRenderer
<PixelFormatTraits_PAL4_MSB
,StdMasks
>(
1976 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1977 pFirstScanline
, pMem
, pPal
,
1978 bitsPerPixel
[nScanlineFormat
], rDamage
);
1980 case Format::FOUR_BIT_LSB_PAL
:
1981 return createRenderer
<PixelFormatTraits_PAL4_LSB
,StdMasks
>(
1982 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1983 pFirstScanline
, pMem
, pPal
,
1984 bitsPerPixel
[nScanlineFormat
], rDamage
);
1987 // ----------------------------------------------------------------------
1988 // eight bit formats
1990 case Format::EIGHT_BIT_GREY
:
1991 return createRenderer
<PixelFormatTraits_GREY8
,StdMasks
>(
1992 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1993 pFirstScanline
, pMem
, pPal
, rDamage
);
1995 case Format::EIGHT_BIT_PAL
:
1996 return createRenderer
<PixelFormatTraits_PAL8
,StdMasks
>(
1997 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
1998 pFirstScanline
, pMem
, pPal
,
1999 bitsPerPixel
[nScanlineFormat
], rDamage
);
2002 // ----------------------------------------------------------------------
2003 // sixteen bit formats
2005 case Format::SIXTEEN_BIT_LSB_TC_MASK
:
2006 return createRenderer
<PixelFormatTraits_RGB16_565_LSB
,StdMasks
>(
2007 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2008 pFirstScanline
, pMem
, pPal
, rDamage
);
2010 case Format::SIXTEEN_BIT_MSB_TC_MASK
:
2011 return createRenderer
<PixelFormatTraits_RGB16_565_MSB
,StdMasks
>(
2012 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2013 pFirstScanline
, pMem
, pPal
, rDamage
);
2016 // ----------------------------------------------------------------------
2017 // twentyfour bit formats
2018 case Format::TWENTYFOUR_BIT_TC_MASK
:
2019 return createRenderer
<PixelFormatTraits_BGR24
,StdMasks
>(
2020 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2021 pFirstScanline
, pMem
, pPal
, rDamage
);
2024 // ----------------------------------------------------------------------
2025 // thirtytwo bit formats
2027 case Format::THIRTYTWO_BIT_TC_MASK_BGRA
:
2028 return createRenderer
<PixelFormatTraits_BGRX32_8888
,StdMasks
>(
2029 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2030 pFirstScanline
, pMem
, pPal
, rDamage
);
2032 case Format::THIRTYTWO_BIT_TC_MASK_ARGB
:
2033 return createRenderer
<PixelFormatTraits_XRGB32_8888
,StdMasks
>(
2034 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2035 pFirstScanline
, pMem
, pPal
, rDamage
);
2037 case Format::THIRTYTWO_BIT_TC_MASK_ABGR
:
2038 return createRenderer
<PixelFormatTraits_XBGR32_8888
,StdMasks
>(
2039 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2040 pFirstScanline
, pMem
, pPal
, rDamage
);
2042 case Format::THIRTYTWO_BIT_TC_MASK_RGBA
:
2043 return createRenderer
<PixelFormatTraits_RGBX32_8888
,StdMasks
>(
2044 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2045 pFirstScanline
, pMem
, pPal
, rDamage
);
2048 // TODO(F3): other formats not yet implemented
2049 return BitmapDeviceSharedPtr();
2052 BitmapDeviceSharedPtr
createBitmapDeviceImpl( const basegfx::B2IVector
& rSize
,
2054 sal_Int32 nScanlineFormat
,
2055 boost::shared_array
< sal_uInt8
> pMem
,
2056 PaletteMemorySharedVector pPal
,
2057 const basegfx::B2IBox
* pSubset
,
2058 const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
)
2060 BitmapDeviceSharedPtr
result( createBitmapDeviceImplInner( rSize
, bTopDown
, nScanlineFormat
, pMem
, pPal
, pSubset
, rDamage
) );
2063 std::ostringstream subset
;
2066 subset
<< " subset=" << pSubset
->getWidth() << "x" << pSubset
->getHeight() << "@(" << pSubset
->getMinX() << "," << pSubset
->getMinY() << ")";
2068 SAL_INFO( "basebmp.bitmapdevice",
2069 "createBitmapDevice: "
2070 << rSize
.getX() << "x" << rSize
.getY()
2071 << (bTopDown
? " top-down " : " bottom-up ")
2072 << Format::formatName(nScanlineFormat
)
2074 << " = " << result
.get() );
2081 BitmapDeviceSharedPtr
createBitmapDevice( const basegfx::B2IVector
& rSize
,
2083 sal_Int32 nScanlineFormat
)
2085 return createBitmapDeviceImpl( rSize
,
2088 boost::shared_array
< sal_uInt8
>(),
2089 PaletteMemorySharedVector(),
2091 IBitmapDeviceDamageTrackerSharedPtr() );
2094 BitmapDeviceSharedPtr
createBitmapDevice( const basegfx::B2IVector
& rSize
,
2096 sal_Int32 nScanlineFormat
,
2097 const PaletteMemorySharedVector
& rPalette
)
2099 return createBitmapDeviceImpl( rSize
,
2102 boost::shared_array
< sal_uInt8
>(),
2105 IBitmapDeviceDamageTrackerSharedPtr() );
2108 BitmapDeviceSharedPtr
createBitmapDevice( const basegfx::B2IVector
& rSize
,
2110 sal_Int32 nScanlineFormat
,
2111 const RawMemorySharedArray
& rMem
,
2112 const PaletteMemorySharedVector
& rPalette
)
2114 return createBitmapDeviceImpl( rSize
,
2120 IBitmapDeviceDamageTrackerSharedPtr() );
2123 BitmapDeviceSharedPtr
subsetBitmapDevice( const BitmapDeviceSharedPtr
& rProto
,
2124 const basegfx::B2IBox
& rSubset
)
2126 SAL_INFO( "basebmp.bitmapdevice", "subsetBitmapDevice: proto=" << rProto
.get() );
2127 return createBitmapDeviceImpl( rProto
->getSize(),
2128 rProto
->isTopDown(),
2129 rProto
->getScanlineFormat(),
2130 rProto
->getBuffer(),
2131 rProto
->getPalette(),
2133 rProto
->getDamageTracker() );
2136 BitmapDeviceSharedPtr
cloneBitmapDevice( const basegfx::B2IVector
& rSize
,
2137 const BitmapDeviceSharedPtr
& rProto
)
2139 return createBitmapDeviceImpl( rSize
,
2140 rProto
->isTopDown(),
2141 rProto
->getScanlineFormat(),
2142 boost::shared_array
< sal_uInt8
>(),
2143 rProto
->getPalette(),
2145 rProto
->getDamageTracker() );
2148 //----------------------------------------------------------------------------------
2150 /// Clone our device, with GenericImageAccessor to handle all formats
2151 BitmapDeviceSharedPtr
BitmapDevice::getGenericRenderer() const
2153 return mpImpl
->mpGenericRenderer
;
2156 } // namespace basebmp
2158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */