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 .
20 #include <sal/config.h>
25 #include <basebmp/bitmapdevice.hxx>
27 #include <basebmp/compositeiterator.hxx>
28 #include <basebmp/iteratortraits.hxx>
30 #include <basebmp/accessor.hxx>
31 #include <basebmp/accessortraits.hxx>
32 #include <basebmp/accessoradapters.hxx>
33 #include <basebmp/colorblendaccessoradapter.hxx>
35 #include <basebmp/color.hxx>
36 #include <basebmp/colormisc.hxx>
37 #include <basebmp/colortraits.hxx>
39 #include <basebmp/greylevelformats.hxx>
40 #include <basebmp/paletteformats.hxx>
41 #include <basebmp/rgbmaskpixelformats.hxx>
42 #include <basebmp/rgb24pixelformats.hxx>
44 #include <basebmp/scanlineformats.hxx>
45 #include <basebmp/fillimage.hxx>
46 #include <basebmp/scaleimage.hxx>
47 #include <basebmp/clippedlinerenderer.hxx>
48 #include <basebmp/polypolygonrenderer.hxx>
49 #include <basebmp/genericcolorimageaccessor.hxx>
51 #include <basebmp/tools.hxx>
52 #include "intconversion.hxx"
54 #include <rtl/alloc.h>
55 #include <osl/diagnose.h>
57 #include <basegfx/tools/tools.hxx>
58 #include <basegfx/tools/canvastools.hxx>
59 #include <basegfx/range/b2ibox.hxx>
60 #include <basegfx/range/b2irange.hxx>
61 #include <basegfx/range/b2drange.hxx>
62 #include <basegfx/polygon/b2dpolygon.hxx>
63 #include <basegfx/polygon/b2dpolygontools.hxx>
64 #include <basegfx/polygon/b2dpolypolygontools.hxx>
65 #include <basegfx/point/b2ipoint.hxx>
66 #include <basegfx/vector/b2ivector.hxx>
68 #include <vigra/iteratortraits.hxx>
69 #include <vigra/rgbvalue.hxx>
70 #include <vigra/copyimage.hxx>
71 #include <vigra/tuple.hxx>
77 /// componentwise xor of an RGBValue (missing from rgbvalue.hxx)
78 template< class Value
, unsigned int RedIndex
, unsigned int BlueIndex
, unsigned int GreenIndex
>
79 inline RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
>
80 operator^( RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
> const& lhs
,
81 RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
> const& rhs
)
83 RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
> res(
94 static const sal_uInt8 bitsPerPixel
[] =
97 1, // ONE_BIT_MSB_GREY
98 1, // ONE_BIT_LSB_GREY
100 1, // ONE_BIT_LSB_PAL
101 4, // FOUR_BIT_MSB_GREY
102 4, // FOUR_BIT_LSB_GREY
103 4, // FOUR_BIT_MSB_PAL
104 4, // FOUR_BIT_LSB_PAL
107 16, // SIXTEEN_BIT_LSB_TC_MASK
108 16, // SIXTEEN_BIT_MSB_TC_MASK
109 24, // TWENTYFOUR_BIT_TC_MASK
110 32, // THIRTYTWO_BIT_TC_MASK_BGRA
111 32, // THIRTYTWO_BIT_TC_MASK_ARGB
112 32, // THIRTYTWO_BIT_TC_MASK_ABGR
113 32, // THIRTYTWO_BIT_TC_MASK_RGBA
118 /** Create the type for an accessor that takes the (mask,bitmap)
119 input value generated from a JoinImageAccessorAdapter, and
120 pipe that through a mask functor.
123 Destination bitmap accessor
126 Input accessor, is expected to generate a std::pair as the
130 Either FastMask or NoFastMask, depending on whether the mask
131 is guaranteed to contain only 0s and 1s.
133 template< class DestAccessor
,
134 class JoinedAccessor
,
136 typename MaskFunctorMode
> struct masked_input_splitting_accessor
138 typedef BinarySetterFunctionAccessorAdapter
<
140 BinaryFunctorSplittingWrapper
<
141 typename outputMaskFunctorSelector
<
142 typename
JoinedAccessor::value_type::first_type
,
143 typename
JoinedAccessor::value_type::second_type
,
145 MaskFunctorMode
>::type
> > type
;
150 // Actual BitmapDevice implementation (templatized by accessor and iterator)
152 /** Implementation of the BitmapDevice interface
155 Iterator to access bitmap memory
158 Raw accessor, to access pixel values directly
160 @tpl AccessorSelector
161 Accessor adapter selector, which, when applying the nested
162 template metafunction wrap_accessor to one of the raw bitmap
163 accessors, yields a member type named 'type', which is a
164 wrapped accessor that map color values.
167 Traits template, containing nested traits
168 clipmask_format_traits and alphamask_format_traits, which
169 determine what specialized formats are to be used for clip and
170 alpha masks. With those mask formats, clipping and alpha
171 blending is handled natively.
173 template< class DestIterator
,
175 class AccessorSelector
,
176 class Masks
> class BitmapRenderer
:
180 typedef DestIterator dest_iterator_type
;
181 typedef RawAccessor raw_accessor_type
;
182 typedef AccessorSelector accessor_selector
;
184 typedef typename
Masks::clipmask_format_traits::iterator_type mask_iterator_type
;
185 typedef typename
Masks::clipmask_format_traits::raw_accessor_type mask_rawaccessor_type
;
186 typedef typename
Masks::clipmask_format_traits::accessor_selector mask_accessorselector_type
;
188 typedef typename
Masks::alphamask_format_traits::iterator_type alphamask_iterator_type
;
189 typedef typename
Masks::alphamask_format_traits::raw_accessor_type alphamask_rawaccessor_type
;
190 typedef typename
Masks::alphamask_format_traits::accessor_selector alphamask_accessorselector_type
;
192 typedef typename
AccessorSelector::template wrap_accessor
<
193 raw_accessor_type
>::type dest_accessor_type
;
195 typedef AccessorTraits
< dest_accessor_type
> accessor_traits
;
196 typedef CompositeIterator2D
< dest_iterator_type
,
197 mask_iterator_type
> composite_iterator_type
;
198 typedef CompositeIterator2D
< vigra::Diff2D
,
199 vigra::Diff2D
> generic_composite_iterator_type
;
201 typedef BitmapRenderer
<mask_iterator_type
,
202 mask_rawaccessor_type
,
203 mask_accessorselector_type
,
204 Masks
> mask_bitmap_type
;
205 typedef BitmapRenderer
<alphamask_iterator_type
,
206 alphamask_rawaccessor_type
,
207 alphamask_accessorselector_type
,
208 Masks
> alphamask_bitmap_type
;
210 // -------------------------------------------------------
212 typedef AccessorTraits
< raw_accessor_type
> raw_accessor_traits
;
213 typedef typename uInt32Converter
<
214 typename
raw_accessor_type::value_type
>::to to_uint32_functor
;
216 // -------------------------------------------------------
218 typedef typename
raw_accessor_traits::xor_accessor raw_xor_accessor_type
;
219 typedef AccessorTraits
<raw_xor_accessor_type
> raw_xor_accessor_traits
;
220 typedef typename
accessor_selector::template wrap_accessor
<
221 raw_xor_accessor_type
>::type xor_accessor_type
;
222 typedef AccessorTraits
<xor_accessor_type
> xor_accessor_traits
;
224 // -------------------------------------------------------
226 typedef typename
raw_accessor_traits::template masked_accessor
<
227 mask_rawaccessor_type
,
230 Masks::clipmask_polarity
>::type raw_maskedaccessor_type
;
231 typedef typename
accessor_selector::template wrap_accessor
<
232 raw_maskedaccessor_type
>::type masked_accessor_type
;
233 typedef typename AccessorTraits
<
234 raw_maskedaccessor_type
>::xor_accessor raw_maskedxor_accessor_type
;
235 typedef typename
accessor_selector::template wrap_accessor
<
236 raw_maskedxor_accessor_type
>::type masked_xoraccessor_type
;
238 // -------------------------------------------------------
240 // ((iter,mask),mask) special case (e.g. for clipped
241 // drawMaskedColor())
242 typedef AccessorTraits
< raw_maskedaccessor_type
> raw_maskedaccessor_traits
;
243 typedef typename
raw_maskedaccessor_traits::template masked_accessor
<
244 mask_rawaccessor_type
,
245 composite_iterator_type
,
247 Masks::clipmask_polarity
>::type raw_maskedmask_accessor_type
;
249 typedef CompositeIterator2D
<
250 composite_iterator_type
,
251 mask_iterator_type
> composite_composite_mask_iterator_type
;
253 // -------------------------------------------------------
255 typedef ConstantColorBlendSetterAccessorAdapter
<
257 typename
alphamask_rawaccessor_type::value_type
,
258 Masks::alphamask_polarity
> colorblend_accessor_type
;
259 typedef AccessorTraits
<colorblend_accessor_type
> colorblend_accessor_traits
;
260 typedef typename
colorblend_accessor_traits::template masked_accessor
<
261 mask_rawaccessor_type
,
264 Masks::clipmask_polarity
>::type masked_colorblend_accessor_type
;
266 // -------------------------------------------------------
268 typedef ConstantColorBlendSetterAccessorAdapter
<
271 Masks::alphamask_polarity
> colorblend_generic_accessor_type
;
272 typedef AccessorTraits
<colorblend_generic_accessor_type
> colorblend_generic_accessor_traits
;
273 typedef typename
colorblend_generic_accessor_traits::template masked_accessor
<
274 mask_rawaccessor_type
,
277 Masks::clipmask_polarity
>::type masked_colorblend_generic_accessor_type
;
279 // -------------------------------------------------------
281 typedef JoinImageAccessorAdapter
< dest_accessor_type
,
282 mask_rawaccessor_type
> joined_image_accessor_type
;
283 typedef JoinImageAccessorAdapter
< GenericColorImageAccessor
,
284 GenericColorImageAccessor
> joined_generic_image_accessor_type
;
286 // -------------------------------------------------------
288 dest_iterator_type maBegin
;
289 typename
accessor_traits::color_lookup maColorLookup
;
290 IBitmapDeviceDamageTrackerSharedPtr mpDamage
;
291 to_uint32_functor maToUInt32Converter
;
292 dest_accessor_type maAccessor
;
293 colorblend_accessor_type maColorBlendAccessor
;
294 colorblend_generic_accessor_type maGenericColorBlendAccessor
;
295 raw_accessor_type maRawAccessor
;
296 xor_accessor_type maXorAccessor
;
297 raw_xor_accessor_type maRawXorAccessor
;
298 masked_accessor_type maMaskedAccessor
;
299 masked_colorblend_accessor_type maMaskedColorBlendAccessor
;
300 masked_colorblend_generic_accessor_type maGenericMaskedColorBlendAccessor
;
301 masked_xoraccessor_type maMaskedXorAccessor
;
302 raw_maskedaccessor_type maRawMaskedAccessor
;
303 raw_maskedxor_accessor_type maRawMaskedXorAccessor
;
304 raw_maskedmask_accessor_type maRawMaskedMaskAccessor
;
307 // -------------------------------------------------------
309 BitmapRenderer( const basegfx::B2IBox
& rBounds
,
310 const basegfx::B2IVector
& rBufferSize
,
311 Format nScanlineFormat
,
312 sal_Int32 nScanlineStride
,
313 sal_uInt8
* pFirstScanline
,
314 dest_iterator_type begin
,
315 raw_accessor_type rawAccessor
,
316 dest_accessor_type accessor
,
317 const RawMemorySharedArray
& rMem
,
318 const PaletteMemorySharedVector
& rPalette
,
319 const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
) :
320 BitmapDevice( rBounds
, rBufferSize
, nScanlineFormat
,
321 nScanlineStride
, pFirstScanline
, rMem
, rPalette
),
325 maToUInt32Converter(),
326 maAccessor( accessor
),
327 maColorBlendAccessor( accessor
),
328 maGenericColorBlendAccessor( accessor
),
329 maRawAccessor( rawAccessor
),
330 maXorAccessor( accessor
),
331 maRawXorAccessor( rawAccessor
),
332 maMaskedAccessor( accessor
),
333 maMaskedColorBlendAccessor( maColorBlendAccessor
),
334 maGenericMaskedColorBlendAccessor( maGenericColorBlendAccessor
),
335 maMaskedXorAccessor( accessor
),
336 maRawMaskedAccessor( rawAccessor
),
337 maRawMaskedXorAccessor( rawAccessor
),
338 maRawMaskedMaskAccessor( rawAccessor
)
343 void damaged( const basegfx::B2IBox
& rDamageRect
) const
346 mpDamage
->damaged( rDamageRect
);
349 void damagedPointSize( const basegfx::B2IPoint
& rPoint
,
350 const basegfx::B2IBox
& rSize
) const
353 basegfx::B2IPoint
aLower( rPoint
.getX() + rSize
.getWidth(),
354 rPoint
.getY() + rSize
.getHeight() );
355 damaged( basegfx::B2IBox( rPoint
, aLower
) );
359 void damagedPixel( const basegfx::B2IPoint
& rDamagePoint
) const
364 sal_Int32
nX(rDamagePoint
.getX());
365 sal_Int32
nY(rDamagePoint
.getY());
366 if (nX
< SAL_MAX_INT32
)
368 if (nY
< SAL_MAX_INT32
)
371 basegfx::B2IPoint
aEnd( nX
, nY
);
372 damaged( basegfx::B2IBox( rDamagePoint
, aEnd
) );
375 boost::shared_ptr
<BitmapRenderer
> getCompatibleBitmap( const BitmapDeviceSharedPtr
& bmp
) const
377 return boost::dynamic_pointer_cast
< BitmapRenderer
>( bmp
);
380 virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr
& bmp
) const
382 // TODO(P1): dynamic_cast usually called twice for
383 // compatible formats
384 return getCompatibleBitmap(bmp
).get() != NULL
;
387 boost::shared_ptr
<mask_bitmap_type
> getCompatibleClipMask( const BitmapDeviceSharedPtr
& bmp
) const
389 boost::shared_ptr
<mask_bitmap_type
> pMask( boost::dynamic_pointer_cast
<mask_bitmap_type
>( bmp
));
394 if( pMask
->getSize() != getSize() )
400 virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr
& bmp
) const
402 // TODO(P1): dynamic_cast usually called twice for
403 // compatible formats
404 return boost::dynamic_pointer_cast
<mask_bitmap_type
>( bmp
).get() != NULL
;
407 boost::shared_ptr
<alphamask_bitmap_type
> getCompatibleAlphaMask( const BitmapDeviceSharedPtr
& bmp
) const
409 return boost::dynamic_pointer_cast
<alphamask_bitmap_type
>( bmp
);
412 virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr
& bmp
) const
414 // TODO(P1): dynamic_cast usually called twice for
415 // compatible formats
416 return getCompatibleAlphaMask( bmp
).get() != NULL
;
419 virtual void clear_i( Color fillColor
,
420 const basegfx::B2IBox
& rBounds
)
422 fillImage(destIterRange(maBegin
,
431 virtual void setPixel_i( const basegfx::B2IPoint
& rPt
,
435 const DestIterator
pixel( maBegin
+
436 vigra::Diff2D(rPt
.getX(),
438 if( drawMode
== DrawMode_XOR
)
439 maXorAccessor
.set( pixelColor
,
442 maAccessor
.set( pixelColor
,
447 virtual void setPixel_i( const basegfx::B2IPoint
& rPt
,
450 const BitmapDeviceSharedPtr
& rClip
)
452 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rClip
) );
455 const vigra::Diff2D
offset(rPt
.getX(),
458 const composite_iterator_type
aIter(
460 pMask
->maBegin
+ offset
);
462 if( drawMode
== DrawMode_XOR
)
463 maMaskedXorAccessor
.set( pixelColor
,
466 maMaskedAccessor
.set( pixelColor
,
471 virtual Color
getPixel_i(const basegfx::B2IPoint
& rPt
)
473 const DestIterator
pixel( maBegin
+
474 vigra::Diff2D(rPt
.getX(),
476 return maAccessor(pixel
);
479 virtual sal_uInt32
getPixelData_i( const basegfx::B2IPoint
& rPt
)
481 const DestIterator
pixel( maBegin
+
482 vigra::Diff2D(rPt
.getX(),
484 return maToUInt32Converter(maRawAccessor(pixel
));
487 template< typename Iterator
, typename Col
, typename RawAcc
>
488 void implRenderLine2( const basegfx::B2IPoint
& rPt1
,
489 const basegfx::B2IPoint
& rPt2
,
490 const basegfx::B2IBox
& rBounds
,
492 const Iterator
& begin
,
493 const RawAcc
& rawAcc
)
495 renderClippedLine( rPt1
,
501 // TODO(P2): perhaps this needs pushing up the stack a bit
502 // to make more complex polygons more efficient ...
503 damaged( basegfx::B2IBox( rPt1
, rPt2
) );
506 template< typename Iterator
, typename Accessor
, typename RawAcc
>
507 void implRenderLine( const basegfx::B2IPoint
& rPt1
,
508 const basegfx::B2IPoint
& rPt2
,
509 const basegfx::B2IBox
& rBounds
,
511 const Iterator
& begin
,
513 const RawAcc
& rawAcc
)
515 implRenderLine2( rPt1
,rPt2
,rBounds
,
522 template< typename Iterator
, typename RawAcc
, typename XorAcc
>
523 void implDrawLine( const basegfx::B2IPoint
& rPt1
,
524 const basegfx::B2IPoint
& rPt2
,
525 const basegfx::B2IBox
& rBounds
,
527 const Iterator
& begin
,
528 const RawAcc
& rawAcc
,
529 const XorAcc
& xorAcc
,
532 if( drawMode
== DrawMode_XOR
)
533 implRenderLine( rPt1
, rPt2
, rBounds
, col
,
534 begin
, maAccessor
, xorAcc
);
536 implRenderLine( rPt1
, rPt2
, rBounds
, col
,
537 begin
, maAccessor
, rawAcc
);
540 virtual void drawLine_i(const basegfx::B2IPoint
& rPt1
,
541 const basegfx::B2IPoint
& rPt2
,
542 const basegfx::B2IBox
& rBounds
,
546 implDrawLine(rPt1
,rPt2
,rBounds
,lineColor
,
548 maRawAccessor
,maRawXorAccessor
,drawMode
);
551 composite_iterator_type
getMaskedIter( const BitmapDeviceSharedPtr
& rClip
) const
553 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rClip
) );
556 return composite_iterator_type( maBegin
,
560 virtual void drawLine_i(const basegfx::B2IPoint
& rPt1
,
561 const basegfx::B2IPoint
& rPt2
,
562 const basegfx::B2IBox
& rBounds
,
565 const BitmapDeviceSharedPtr
& rClip
)
567 implDrawLine(rPt1
,rPt2
,rBounds
,lineColor
,
568 getMaskedIter(rClip
),
570 maRawMaskedXorAccessor
,drawMode
);
573 template< typename Iterator
, typename RawAcc
>
574 void implDrawPolygon( const basegfx::B2DPolygon
& rPoly
,
575 const basegfx::B2IBox
& rBounds
,
577 const Iterator
& begin
,
580 basegfx::B2DPolygon
aPoly( rPoly
);
581 if( rPoly
.areControlPointsUsed() )
582 aPoly
= basegfx::tools::adaptiveSubdivideByCount( rPoly
);
584 const typename
dest_iterator_type::value_type
colorIndex( maColorLookup(
587 const sal_uInt32
nVertices( aPoly
.count() );
588 for( sal_uInt32 i
=1; i
<nVertices
; ++i
)
589 implRenderLine2( basegfx::fround(aPoly
.getB2DPoint(i
-1)),
590 basegfx::fround(aPoly
.getB2DPoint(i
)),
596 if( nVertices
> 1 && aPoly
.isClosed() )
597 implRenderLine2( basegfx::fround(aPoly
.getB2DPoint(nVertices
-1)),
598 basegfx::fround(aPoly
.getB2DPoint(0)),
605 virtual void drawPolygon_i(const basegfx::B2DPolygon
& rPoly
,
606 const basegfx::B2IBox
& rBounds
,
610 if( drawMode
== DrawMode_XOR
)
611 implDrawPolygon( rPoly
, rBounds
, lineColor
,
615 implDrawPolygon( rPoly
, rBounds
, lineColor
,
620 virtual void drawPolygon_i(const basegfx::B2DPolygon
& rPoly
,
621 const basegfx::B2IBox
& rBounds
,
624 const BitmapDeviceSharedPtr
& rClip
)
626 if( drawMode
== DrawMode_XOR
)
627 implDrawPolygon( rPoly
, rBounds
, lineColor
,
628 getMaskedIter(rClip
),
629 maRawMaskedXorAccessor
);
631 implDrawPolygon( rPoly
, rBounds
, lineColor
,
632 getMaskedIter(rClip
),
633 maRawMaskedAccessor
);
636 template< typename Iterator
, typename RawAcc
>
637 void implFillPolyPolygon( const basegfx::B2DPolyPolygon
& rPoly
,
639 const Iterator
& begin
,
641 const basegfx::B2IBox
& rBounds
)
643 basegfx::B2DPolyPolygon
aPoly( rPoly
);
644 if( rPoly
.areControlPointsUsed() )
645 aPoly
= basegfx::tools::adaptiveSubdivideByCount( rPoly
);
647 renderClippedPolyPolygon( begin
,
649 maColorLookup( maAccessor
,
653 basegfx::FillRule_EVEN_ODD
);
657 basegfx::B2DRange
const aPolyBounds( basegfx::tools::getRange(aPoly
) );
658 damaged( basegfx::unotools::b2ISurroundingBoxFromB2DRange( aPolyBounds
) );
662 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon
& rPoly
,
665 const basegfx::B2IBox
& rBounds
)
667 if( drawMode
== DrawMode_XOR
)
668 implFillPolyPolygon( rPoly
, fillColor
,
673 implFillPolyPolygon( rPoly
, fillColor
,
679 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon
& rPoly
,
682 const basegfx::B2IBox
& rBounds
,
683 const BitmapDeviceSharedPtr
& rClip
)
685 if( drawMode
== DrawMode_XOR
)
686 implFillPolyPolygon( rPoly
, fillColor
,
687 getMaskedIter(rClip
),
688 maRawMaskedXorAccessor
,
691 implFillPolyPolygon( rPoly
, fillColor
,
692 getMaskedIter(rClip
),
697 template< typename Iterator
, typename RawAcc
>
698 void implDrawBitmap(const BitmapDeviceSharedPtr
& rSrcBitmap
,
699 const basegfx::B2IBox
& rSrcRect
,
700 const basegfx::B2IBox
& rDstRect
,
701 const Iterator
& begin
,
704 boost::shared_ptr
<BitmapRenderer
> pSrcBmp( getCompatibleBitmap(rSrcBitmap
) );
705 OSL_ASSERT( pSrcBmp
);
708 srcIterRange(pSrcBmp
->maBegin
,
709 pSrcBmp
->maRawAccessor
,
714 isSharedBuffer(rSrcBitmap
) );
718 template< typename Iterator
, typename Acc
>
719 void implDrawBitmapGeneric(const BitmapDeviceSharedPtr
& rSrcBitmap
,
720 const basegfx::B2IBox
& rSrcRect
,
721 const basegfx::B2IBox
& rDstRect
,
722 const Iterator
& begin
,
725 GenericColorImageAccessor
aSrcAcc( rSrcBitmap
);
728 srcIterRange(vigra::Diff2D(),
737 void implDrawBitmapDirect(const BitmapDeviceSharedPtr
& rSrcBitmap
,
738 const basegfx::B2IBox
& rSrcRect
,
739 const basegfx::B2IBox
& rDstRect
)
741 sal_Int32 nSrcX
= rSrcRect
.getMinX();
742 sal_Int32 nSrcY
= rSrcRect
.getMinY();
743 sal_Int32 nSrcWidth
= rSrcRect
.getWidth();
744 sal_Int32 nSrcHeight
= rSrcRect
.getHeight();
745 sal_Int32 nDestX
= rDstRect
.getMinX();
746 sal_Int32 nDestY
= rDstRect
.getMinY();
748 char* dstBuf
= (char*)getBuffer().get();
749 char* srcBuf
= (char*)rSrcBitmap
->getBuffer().get();
750 sal_Int32 dstStride
= getScanlineStride();
751 sal_Int32 srcStride
= rSrcBitmap
->getScanlineStride();
752 sal_Int32 bytesPerPixel
= (bitsPerPixel
[getScanlineFormat()] + 7) >> 3; // round up to bytes
753 bool dstTopDown
= isTopDown();
754 bool srcTopDown
= rSrcBitmap
->isTopDown();
756 if (dstBuf
== srcBuf
&& nSrcY
< nDestY
) // reverse copy order to avoid overlapping
758 nSrcY
= getBufferSize().getY() - nSrcY
- nSrcHeight
;
759 nDestY
= getBufferSize().getY() - nDestY
- nSrcHeight
;
760 srcTopDown
= !srcTopDown
;
761 dstTopDown
= !dstTopDown
;
766 dstBuf
+= dstStride
* (getBufferSize().getY() - 1);
767 dstStride
= -dstStride
;
772 srcBuf
+= srcStride
* (rSrcBitmap
->getBufferSize().getY() - 1);
773 srcStride
= -srcStride
;
776 char* dstline
= dstBuf
+ dstStride
* nDestY
+ nDestX
* bytesPerPixel
;
777 char* srcline
= srcBuf
+ srcStride
* nSrcY
+ nSrcX
* bytesPerPixel
;
778 sal_Int32 lineBytes
= nSrcWidth
* bytesPerPixel
;
780 for(; 0 < nSrcHeight
; nSrcHeight
--)
782 memmove(dstline
, srcline
, lineBytes
);
783 dstline
+= dstStride
;
784 srcline
+= srcStride
;
788 virtual void drawBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
789 const basegfx::B2IBox
& rSrcRect
,
790 const basegfx::B2IBox
& rDstRect
,
793 if( isCompatibleBitmap( rSrcBitmap
) )
795 if( drawMode
== DrawMode_XOR
)
796 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
799 else if (bitsPerPixel
[getScanlineFormat()] >= 8
800 && rSrcRect
.getWidth() == rDstRect
.getWidth() && rSrcRect
.getHeight() == rDstRect
.getHeight()
801 && rSrcBitmap
->getScanlineFormat() == getScanlineFormat())
802 implDrawBitmapDirect(rSrcBitmap
, rSrcRect
, rDstRect
);
804 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
810 if( drawMode
== DrawMode_XOR
)
811 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
815 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
822 virtual void drawBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
823 const basegfx::B2IBox
& rSrcRect
,
824 const basegfx::B2IBox
& rDstRect
,
826 const BitmapDeviceSharedPtr
& rClip
)
828 if( isCompatibleBitmap( rSrcBitmap
) )
830 if( drawMode
== DrawMode_XOR
)
831 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
832 getMaskedIter(rClip
),
833 maRawMaskedXorAccessor
);
835 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
836 getMaskedIter(rClip
),
837 maRawMaskedAccessor
);
841 if( drawMode
== DrawMode_XOR
)
842 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
843 getMaskedIter(rClip
),
844 maMaskedXorAccessor
);
846 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
847 getMaskedIter(rClip
),
853 virtual void drawMaskedColor_i(Color aSrcColor
,
854 const BitmapDeviceSharedPtr
& rAlphaMask
,
855 const basegfx::B2IBox
& rSrcRect
,
856 const basegfx::B2IPoint
& rDstPoint
)
858 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rAlphaMask
) );
859 boost::shared_ptr
<alphamask_bitmap_type
> pAlpha( getCompatibleAlphaMask(rAlphaMask
) );
863 maColorBlendAccessor
.setColor( aSrcColor
);
865 vigra::copyImage( srcIterRange(pAlpha
->maBegin
,
866 pAlpha
->maRawAccessor
,
869 maColorBlendAccessor
,
874 const composite_iterator_type
aBegin(
875 maBegin
+ vigra::Diff2D(rDstPoint
.getX(),
877 pMask
->maBegin
+ topLeft(rSrcRect
) );
880 aBegin
+ vigra::Diff2D(rSrcRect
.getWidth(),
881 rSrcRect
.getHeight()),
889 GenericColorImageAccessor
aSrcAcc( rAlphaMask
);
890 maGenericColorBlendAccessor
.setColor( aSrcColor
);
892 vigra::copyImage( srcIterRange(vigra::Diff2D(),
896 maGenericColorBlendAccessor
,
899 damagedPointSize( rDstPoint
, rSrcRect
);
902 virtual void drawMaskedColor_i(Color aSrcColor
,
903 const BitmapDeviceSharedPtr
& rAlphaMask
,
904 const basegfx::B2IBox
& rSrcRect
,
905 const basegfx::B2IPoint
& rDstPoint
,
906 const BitmapDeviceSharedPtr
& rClip
)
908 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rAlphaMask
) );
909 boost::shared_ptr
<alphamask_bitmap_type
> pAlpha( getCompatibleAlphaMask(rAlphaMask
) );
913 const composite_iterator_type
aBegin( getMaskedIter(rClip
) );
914 maMaskedColorBlendAccessor
.get1stWrappedAccessor().setColor(
917 vigra::copyImage( srcIterRange(pAlpha
->maBegin
,
918 pAlpha
->maRawAccessor
,
921 maMaskedColorBlendAccessor
,
926 boost::shared_ptr
<mask_bitmap_type
> pClipMask( getCompatibleClipMask(rClip
) );
927 OSL_ASSERT( pClipMask
);
929 // setup a ((iter,mask),clipMask) composite composite
930 // iterator, to pass both masks (clip and alpha mask)
932 const composite_composite_mask_iterator_type
aBegin(
933 composite_iterator_type(
934 maBegin
+ vigra::Diff2D(rDstPoint
.getX(),
936 pMask
->maBegin
+ topLeft(rSrcRect
)),
937 pClipMask
->maBegin
+ vigra::Diff2D(rDstPoint
.getX(),
941 aBegin
+ vigra::Diff2D(rSrcRect
.getWidth(),
942 rSrcRect
.getHeight()),
943 maRawMaskedMaskAccessor
,
950 GenericColorImageAccessor
aSrcAcc( rAlphaMask
);
951 const composite_iterator_type
aBegin( getMaskedIter(rClip
) );
952 maGenericMaskedColorBlendAccessor
.get1stWrappedAccessor().setColor(
955 vigra::copyImage( srcIterRange(vigra::Diff2D(),
959 maGenericMaskedColorBlendAccessor
,
962 damagedPointSize( rDstPoint
, rSrcRect
);
965 template< typename Iterator
, typename Acc
>
966 void implDrawMaskedBitmap(const BitmapDeviceSharedPtr
& rSrcBitmap
,
967 const BitmapDeviceSharedPtr
& rMask
,
968 const basegfx::B2IBox
& rSrcRect
,
969 const basegfx::B2IBox
& rDstRect
,
970 const Iterator
& begin
,
973 boost::shared_ptr
<BitmapRenderer
> pSrcBmp( getCompatibleBitmap(rSrcBitmap
) );
974 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rMask
) );
975 OSL_ASSERT( pMask
&& pSrcBmp
);
978 srcIterRange(composite_iterator_type(
981 joined_image_accessor_type(
983 pMask
->maRawAccessor
),
986 typename masked_input_splitting_accessor
<
988 joined_image_accessor_type
,
989 Masks::clipmask_polarity
,
990 FastMask
>::type(acc
),
992 isSharedBuffer(rSrcBitmap
));
996 template< typename Iterator
, typename Acc
>
997 void implDrawMaskedBitmapGeneric(const BitmapDeviceSharedPtr
& rSrcBitmap
,
998 const BitmapDeviceSharedPtr
& rMask
,
999 const basegfx::B2IBox
& rSrcRect
,
1000 const basegfx::B2IBox
& rDstRect
,
1001 const Iterator
& begin
,
1004 GenericColorImageAccessor
aSrcAcc( rSrcBitmap
);
1005 GenericColorImageAccessor
aMaskAcc( rMask
);
1007 const vigra::Diff2D
aTopLeft(rSrcRect
.getMinX(),
1008 rSrcRect
.getMinY());
1009 const vigra::Diff2D
aBottomRight(rSrcRect
.getMaxX(),
1010 rSrcRect
.getMaxY());
1013 generic_composite_iterator_type(
1015 generic_composite_iterator_type(
1016 aBottomRight
,aBottomRight
),
1017 joined_generic_image_accessor_type(
1020 destIterRange(begin
,
1021 typename masked_input_splitting_accessor
<
1023 joined_generic_image_accessor_type
,
1024 Masks::clipmask_polarity
,
1025 NoFastMask
>::type(acc
),
1027 damaged( rDstRect
);
1030 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
1031 const BitmapDeviceSharedPtr
& rMask
,
1032 const basegfx::B2IBox
& rSrcRect
,
1033 const basegfx::B2IBox
& rDstRect
,
1036 if( isCompatibleClipMask(rMask
) &&
1037 isCompatibleBitmap(rSrcBitmap
) )
1039 if( drawMode
== DrawMode_XOR
)
1040 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1045 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1052 if( drawMode
== DrawMode_XOR
)
1053 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1058 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1063 damaged( rDstRect
);
1066 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
1067 const BitmapDeviceSharedPtr
& rMask
,
1068 const basegfx::B2IBox
& rSrcRect
,
1069 const basegfx::B2IBox
& rDstRect
,
1071 const BitmapDeviceSharedPtr
& rClip
)
1073 if( isCompatibleClipMask(rMask
) &&
1074 isCompatibleBitmap(rSrcBitmap
) )
1076 if( drawMode
== DrawMode_XOR
)
1077 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1079 getMaskedIter(rClip
),
1080 maMaskedXorAccessor
);
1082 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1084 getMaskedIter(rClip
),
1089 if( drawMode
== DrawMode_XOR
)
1090 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1092 getMaskedIter(rClip
),
1093 maMaskedXorAccessor
);
1095 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1097 getMaskedIter(rClip
),
1100 damaged( rDstRect
);
1103 IBitmapDeviceDamageTrackerSharedPtr
getDamageTracker_i() const
1107 void setDamageTracker_i( const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
)
1114 struct ImplBitmapDevice
1116 /** Bitmap memory plus deleter.
1118 Always points to the start of the mem
1120 RawMemorySharedArray mpMem
;
1122 /// Palette memory plus deleter (might be NULL)
1123 PaletteMemorySharedVector mpPalette
;
1125 /** Bounds of the device.
1127 maBounds.getWidth()/getHeight() yield the true size of the
1128 device (i.e. the rectangle given by maBounds covers the device
1129 area under the including-the-bottommost-and-rightmost-pixels
1132 basegfx::B2IBox maBounds
;
1134 //// Size of the actual frame buffer
1135 basegfx::B2IVector maBufferSize
;
1137 /// Scanline format, as provided at the constructor
1138 Format mnScanlineFormat
;
1140 /// Scanline stride. Negative for bottom-to-top formats
1141 sal_Int32 mnScanlineStride
;
1143 /// raw ptr to 0th scanline. used for cloning a generic renderer
1144 sal_uInt8
* mpFirstScanline
;
1146 /** (Optional) device sharing the same memory, and used for input
1147 clip masks/alpha masks/bitmaps that don't match our exact
1150 This is to avoid the combinatorical explosion when dealing
1151 with n bitmap formats, which could be combined with n clip
1152 masks, alpha masks and bitmap masks (yielding a total of n^4
1153 combinations). Since each BitmapRenderer is specialized for
1154 one specific combination of said formats, a lot of duplicate
1155 code would be generated, most of which probably never
1156 used. Therefore, only the most common combinations are
1157 specialized templates, the remainder gets handled by this
1158 generic renderer (via runtime polymorphism).
1160 BitmapDeviceSharedPtr mpGenericRenderer
;
1164 BitmapDevice::BitmapDevice( const basegfx::B2IBox
& rBounds
,
1165 const basegfx::B2IVector
& rBufferSize
,
1166 Format nScanlineFormat
,
1167 sal_Int32 nScanlineStride
,
1168 sal_uInt8
* pFirstScanline
,
1169 const RawMemorySharedArray
& rMem
,
1170 const PaletteMemorySharedVector
& rPalette
) :
1171 mpImpl( new ImplBitmapDevice
)
1173 mpImpl
->mpMem
= rMem
;
1174 mpImpl
->mpPalette
= rPalette
;
1175 mpImpl
->maBounds
= rBounds
;
1176 mpImpl
->maBufferSize
= rBufferSize
;
1177 mpImpl
->mnScanlineFormat
= nScanlineFormat
;
1178 mpImpl
->mnScanlineStride
= nScanlineStride
;
1179 mpImpl
->mpFirstScanline
= pFirstScanline
;
1182 BitmapDevice::~BitmapDevice()
1184 // outline, because of internal ImplBitmapDevice
1185 SAL_INFO( "basebmp.bitmapdevice", "~BitmapDevice(" << this << ")" );
1188 basegfx::B2IVector
BitmapDevice::getSize() const
1190 return basegfx::B2IVector(
1191 mpImpl
->maBounds
.getMaxX() - mpImpl
->maBounds
.getMinX(),
1192 mpImpl
->maBounds
.getMaxY() - mpImpl
->maBounds
.getMinY() );
1195 bool BitmapDevice::isTopDown() const
1197 return mpImpl
->mnScanlineStride
>= 0;
1200 basegfx::B2IVector
BitmapDevice::getBufferSize() const
1202 return mpImpl
->maBufferSize
;
1205 Format
BitmapDevice::getScanlineFormat() const
1207 return mpImpl
->mnScanlineFormat
;
1210 sal_Int32
BitmapDevice::getScanlineStride() const
1212 return mpImpl
->mnScanlineStride
< 0 ?
1213 -mpImpl
->mnScanlineStride
: mpImpl
->mnScanlineStride
;
1216 RawMemorySharedArray
BitmapDevice::getBuffer() const
1218 return mpImpl
->mpMem
;
1221 IBitmapDeviceDamageTrackerSharedPtr
BitmapDevice::getDamageTracker() const
1223 return getDamageTracker_i();
1226 void BitmapDevice::setDamageTracker( const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
)
1228 setDamageTracker_i(rDamage
);
1231 PaletteMemorySharedVector
BitmapDevice::getPalette() const
1233 return mpImpl
->mpPalette
;
1236 bool BitmapDevice::isSharedBuffer( const BitmapDeviceSharedPtr
& rOther
) const
1238 return rOther
.get()->getBuffer().get() == getBuffer().get();
1241 void BitmapDevice::clear( Color fillColor
)
1243 clear_i( fillColor
, mpImpl
->maBounds
);
1246 void BitmapDevice::setPixel( const basegfx::B2IPoint
& rPt
,
1250 if( mpImpl
->maBounds
.isInside(rPt
) )
1251 setPixel_i(rPt
,lineColor
,drawMode
);
1254 void BitmapDevice::setPixel( const basegfx::B2IPoint
& rPt
,
1257 const BitmapDeviceSharedPtr
& rClip
)
1261 setPixel(rPt
,lineColor
,drawMode
);
1265 if( mpImpl
->maBounds
.isInside(rPt
) )
1267 if( isCompatibleClipMask( rClip
) )
1268 setPixel_i(rPt
,lineColor
,drawMode
,rClip
);
1270 getGenericRenderer()->setPixel( rPt
, lineColor
, drawMode
, rClip
);
1274 Color
BitmapDevice::getPixel( const basegfx::B2IPoint
& rPt
)
1276 if( mpImpl
->maBounds
.isInside(rPt
) )
1277 return getPixel_i(rPt
);
1282 sal_uInt32
BitmapDevice::getPixelData( const basegfx::B2IPoint
& rPt
)
1284 if( mpImpl
->maBounds
.isInside(rPt
) )
1285 return getPixelData_i(rPt
);
1290 void BitmapDevice::drawLine( const basegfx::B2IPoint
& rPt1
,
1291 const basegfx::B2IPoint
& rPt2
,
1302 void BitmapDevice::drawLine( const basegfx::B2IPoint
& rPt1
,
1303 const basegfx::B2IPoint
& rPt2
,
1306 const BitmapDeviceSharedPtr
& rClip
)
1310 drawLine(rPt1
,rPt2
,lineColor
,drawMode
);
1314 if( isCompatibleClipMask( rClip
) )
1322 getGenericRenderer()->drawLine( rPt1
, rPt2
, lineColor
,
1326 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon
& rPoly
,
1330 const sal_uInt32
numVertices( rPoly
.count() );
1332 drawPolygon_i( rPoly
,
1334 lineColor
, drawMode
);
1337 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon
& rPoly
,
1340 const BitmapDeviceSharedPtr
& rClip
)
1344 drawPolygon(rPoly
,lineColor
,drawMode
);
1348 const sal_uInt32
numVertices( rPoly
.count() );
1351 if( isCompatibleClipMask( rClip
) )
1352 drawPolygon_i( rPoly
,
1354 lineColor
, drawMode
, rClip
);
1356 getGenericRenderer()->drawPolygon( rPoly
, lineColor
,
1361 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon
& rPoly
,
1365 fillPolyPolygon_i( rPoly
, fillColor
, drawMode
, mpImpl
->maBounds
);
1368 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon
& rPoly
,
1371 const BitmapDeviceSharedPtr
& rClip
)
1375 fillPolyPolygon(rPoly
,fillColor
,drawMode
);
1379 if( isCompatibleClipMask( rClip
) )
1380 fillPolyPolygon_i( rPoly
, fillColor
, drawMode
, mpImpl
->maBounds
, rClip
);
1382 getGenericRenderer()->fillPolyPolygon( rPoly
, fillColor
,
1389 void assertImagePoint( const basegfx::B2IPoint
& rPt
,
1390 const basegfx::B2IBox
& rPermittedRange
)
1392 (void)rPt
; (void)rPermittedRange
;
1393 OSL_ASSERT( rPermittedRange
.isInside(rPt
) );
1396 void assertImageRange( const basegfx::B2IBox
& rRange
,
1397 const basegfx::B2IBox
& rPermittedRange
)
1399 #if OSL_DEBUG_LEVEL > 0
1400 basegfx::B2IBox
aRange( rRange
);
1401 aRange
.intersect( rPermittedRange
);
1403 OSL_ASSERT( aRange
== rRange
);
1405 (void)rRange
; (void)rPermittedRange
;
1409 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1410 // to basegfx, and use here!
1411 bool clipAreaImpl( ::basegfx::B2IBox
& io_rSourceArea
,
1412 ::basegfx::B2IPoint
& io_rDestPoint
,
1413 const ::basegfx::B2IBox
& rSourceBounds
,
1414 const ::basegfx::B2IBox
& rDestBounds
)
1416 const ::basegfx::B2IPoint
aSourceTopLeft(
1417 io_rSourceArea
.getMinimum() );
1419 ::basegfx::B2IBox
aLocalSourceArea( io_rSourceArea
);
1421 // clip source area (which must be inside rSourceBounds)
1422 aLocalSourceArea
.intersect( rSourceBounds
);
1424 if( aLocalSourceArea
.isEmpty() )
1427 // calc relative new source area points (relative to orig
1429 const ::basegfx::B2IVector
aUpperLeftOffset(
1430 aLocalSourceArea
.getMinimum()-aSourceTopLeft
);
1431 const ::basegfx::B2IVector
aLowerRightOffset(
1432 aLocalSourceArea
.getMaximum()-aSourceTopLeft
);
1434 ::basegfx::B2IBox
aLocalDestArea( io_rDestPoint
+ aUpperLeftOffset
,
1435 io_rDestPoint
+ aLowerRightOffset
);
1437 // clip dest area (which must be inside rDestBounds)
1438 aLocalDestArea
.intersect( rDestBounds
);
1440 if( aLocalDestArea
.isEmpty() )
1443 // calc relative new dest area points (relative to orig
1445 const ::basegfx::B2IVector
aDestUpperLeftOffset(
1446 aLocalDestArea
.getMinimum()-io_rDestPoint
);
1447 const ::basegfx::B2IVector
aDestLowerRightOffset(
1448 aLocalDestArea
.getMaximum()-io_rDestPoint
);
1450 io_rSourceArea
= ::basegfx::B2IBox( aSourceTopLeft
+ aDestUpperLeftOffset
,
1451 aSourceTopLeft
+ aDestLowerRightOffset
);
1452 io_rDestPoint
= aLocalDestArea
.getMinimum();
1457 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1458 // to basegfx, and use here!
1459 bool clipAreaImpl( ::basegfx::B2IBox
& io_rDestArea
,
1460 ::basegfx::B2IBox
& io_rSourceArea
,
1461 const ::basegfx::B2IBox
& rDestBounds
,
1462 const ::basegfx::B2IBox
& rSourceBounds
)
1464 // extract inherent scale
1465 const double nScaleX( io_rDestArea
.getWidth() / (double)io_rSourceArea
.getWidth() );
1466 const double nScaleY( io_rDestArea
.getHeight() / (double)io_rSourceArea
.getHeight() );
1468 // extract range origins
1469 const basegfx::B2IPoint
aDestTopLeft(
1470 io_rDestArea
.getMinimum() );
1471 const ::basegfx::B2IPoint
aSourceTopLeft(
1472 io_rSourceArea
.getMinimum() );
1474 ::basegfx::B2IBox
aLocalSourceArea( io_rSourceArea
);
1476 // clip source area (which must be inside rSourceBounds)
1477 aLocalSourceArea
.intersect( rSourceBounds
);
1479 if( aLocalSourceArea
.isEmpty() )
1482 // calc relative new source area points (relative to orig
1484 const ::basegfx::B2IVector
aUpperLeftOffset(
1485 aLocalSourceArea
.getMinimum()-aSourceTopLeft
);
1486 const ::basegfx::B2IVector
aLowerRightOffset(
1487 aLocalSourceArea
.getMaximum()-aSourceTopLeft
);
1489 ::basegfx::B2IBox
aLocalDestArea( basegfx::fround(aDestTopLeft
.getX() + nScaleX
*aUpperLeftOffset
.getX()),
1490 basegfx::fround(aDestTopLeft
.getY() + nScaleY
*aUpperLeftOffset
.getY()),
1491 basegfx::fround(aDestTopLeft
.getX() + nScaleX
*aLowerRightOffset
.getX()),
1492 basegfx::fround(aDestTopLeft
.getY() + nScaleY
*aLowerRightOffset
.getY()) );
1494 // clip dest area (which must be inside rDestBounds)
1495 aLocalDestArea
.intersect( rDestBounds
);
1497 if( aLocalDestArea
.isEmpty() )
1500 // calc relative new dest area points (relative to orig
1502 const ::basegfx::B2IVector
aDestUpperLeftOffset(
1503 aLocalDestArea
.getMinimum()-aDestTopLeft
);
1504 const ::basegfx::B2IVector
aDestLowerRightOffset(
1505 aLocalDestArea
.getMaximum()-aDestTopLeft
);
1507 io_rSourceArea
= ::basegfx::B2IBox( basegfx::fround(aSourceTopLeft
.getX() + aDestUpperLeftOffset
.getX()/nScaleX
),
1508 basegfx::fround(aSourceTopLeft
.getY() + aDestUpperLeftOffset
.getY()/nScaleY
),
1509 basegfx::fround(aSourceTopLeft
.getX() + aDestLowerRightOffset
.getX()/nScaleX
),
1510 basegfx::fround(aSourceTopLeft
.getY() + aDestLowerRightOffset
.getY()/nScaleY
) );
1511 io_rDestArea
= aLocalDestArea
;
1513 // final source area clip (chopping round-offs)
1514 io_rSourceArea
.intersect( rSourceBounds
);
1516 if( io_rSourceArea
.isEmpty() )
1524 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1525 const basegfx::B2IBox
& rSrcRect
,
1526 const basegfx::B2IBox
& rDstRect
,
1529 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1530 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1531 basegfx::B2IBox
aSrcRange( rSrcRect
);
1532 basegfx::B2IBox
aDestRange( rDstRect
);
1534 if( clipAreaImpl( aDestRange
,
1539 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1540 assertImageRange(aSrcRange
,aSrcBounds
);
1542 drawBitmap_i( rSrcBitmap
, aSrcRange
, aDestRange
, drawMode
);
1546 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1547 const basegfx::B2IBox
& rSrcRect
,
1548 const basegfx::B2IBox
& rDstRect
,
1550 const BitmapDeviceSharedPtr
& rClip
)
1554 drawBitmap(rSrcBitmap
,rSrcRect
,rDstRect
,drawMode
);
1558 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1559 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1560 basegfx::B2IBox
aSrcRange( rSrcRect
);
1561 basegfx::B2IBox
aDestRange( rDstRect
);
1563 if( clipAreaImpl( aDestRange
,
1568 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1569 assertImageRange(aSrcRange
,aSrcBounds
);
1571 if( isCompatibleClipMask( rClip
) )
1573 drawBitmap_i( rSrcBitmap
, aSrcRange
, aDestRange
, drawMode
, rClip
);
1577 getGenericRenderer()->drawBitmap( rSrcBitmap
, rSrcRect
,
1578 rDstRect
, drawMode
, rClip
);
1583 void BitmapDevice::drawMaskedColor( Color aSrcColor
,
1584 const BitmapDeviceSharedPtr
& rAlphaMask
,
1585 const basegfx::B2IBox
& rSrcRect
,
1586 const basegfx::B2IPoint
& rDstPoint
)
1588 const basegfx::B2IVector
& rSrcSize( rAlphaMask
->getSize() );
1589 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1590 basegfx::B2IBox
aSrcRange( rSrcRect
);
1591 basegfx::B2IPoint
aDestPoint( rDstPoint
);
1593 if( clipAreaImpl( aSrcRange
,
1598 assertImagePoint(aDestPoint
,mpImpl
->maBounds
);
1599 assertImageRange(aSrcRange
,aSrcBounds
);
1601 if( isSharedBuffer(rAlphaMask
) )
1603 // src == dest, copy rAlphaMask beforehand
1604 // ---------------------------------------------------
1606 const basegfx::B2ITuple
aSize( aSrcRange
.getWidth(),
1607 aSrcRange
.getHeight() );
1608 BitmapDeviceSharedPtr
pAlphaCopy(
1609 cloneBitmapDevice( aSize
,
1610 shared_from_this()) );
1611 basegfx::B2ITuple aGcc3WorkaroundTemporary
;
1612 const basegfx::B2IBox
aAlphaRange( aGcc3WorkaroundTemporary
,
1614 pAlphaCopy
->drawBitmap(rAlphaMask
,
1618 drawMaskedColor_i( aSrcColor
, pAlphaCopy
, aAlphaRange
, aDestPoint
);
1622 drawMaskedColor_i( aSrcColor
, rAlphaMask
, aSrcRange
, aDestPoint
);
1627 void BitmapDevice::drawMaskedColor( Color aSrcColor
,
1628 const BitmapDeviceSharedPtr
& rAlphaMask
,
1629 const basegfx::B2IBox
& rSrcRect
,
1630 const basegfx::B2IPoint
& rDstPoint
,
1631 const BitmapDeviceSharedPtr
& rClip
)
1635 drawMaskedColor(aSrcColor
,rAlphaMask
,rSrcRect
,rDstPoint
);
1639 const basegfx::B2IVector
& rSrcSize( rAlphaMask
->getSize() );
1640 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1641 basegfx::B2IBox
aSrcRange( rSrcRect
);
1642 basegfx::B2IPoint
aDestPoint( rDstPoint
);
1644 if( clipAreaImpl( aSrcRange
,
1649 assertImagePoint(aDestPoint
,mpImpl
->maBounds
);
1650 assertImageRange(aSrcRange
,aSrcBounds
);
1652 if( isCompatibleClipMask( rClip
) )
1654 if( isSharedBuffer(rAlphaMask
) )
1656 // src == dest, copy rAlphaMask beforehand
1657 // ---------------------------------------------------
1659 const basegfx::B2ITuple
aSize( aSrcRange
.getWidth(),
1660 aSrcRange
.getHeight() );
1661 BitmapDeviceSharedPtr
pAlphaCopy(
1662 cloneBitmapDevice( aSize
,
1663 shared_from_this()) );
1664 basegfx::B2ITuple aGcc3WorkaroundTemporary
;
1665 const basegfx::B2IBox
aAlphaRange( aGcc3WorkaroundTemporary
,
1667 pAlphaCopy
->drawBitmap(rAlphaMask
,
1671 drawMaskedColor_i( aSrcColor
, pAlphaCopy
, aAlphaRange
, aDestPoint
, rClip
);
1675 drawMaskedColor_i( aSrcColor
, rAlphaMask
, aSrcRange
, aDestPoint
, rClip
);
1680 getGenericRenderer()->drawMaskedColor( aSrcColor
, rAlphaMask
,
1681 rSrcRect
, rDstPoint
, rClip
);
1686 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1687 const BitmapDeviceSharedPtr
& rMask
,
1688 const basegfx::B2IBox
& rSrcRect
,
1689 const basegfx::B2IBox
& rDstRect
,
1692 OSL_ASSERT( rMask
->getSize() == rSrcBitmap
->getSize() );
1694 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1695 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1696 basegfx::B2IBox
aSrcRange( rSrcRect
);
1697 basegfx::B2IBox
aDestRange( rDstRect
);
1699 if( clipAreaImpl( aDestRange
,
1704 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1705 assertImageRange(aSrcRange
,aSrcBounds
);
1707 drawMaskedBitmap_i( rSrcBitmap
, rMask
, aSrcRange
, aDestRange
, drawMode
);
1711 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1712 const BitmapDeviceSharedPtr
& rMask
,
1713 const basegfx::B2IBox
& rSrcRect
,
1714 const basegfx::B2IBox
& rDstRect
,
1716 const BitmapDeviceSharedPtr
& rClip
)
1720 drawMaskedBitmap(rSrcBitmap
,rMask
,rSrcRect
,rDstRect
,drawMode
);
1724 OSL_ASSERT( rMask
->getSize() == rSrcBitmap
->getSize() );
1726 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1727 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1728 basegfx::B2IBox
aSrcRange( rSrcRect
);
1729 basegfx::B2IBox
aDestRange( rDstRect
);
1731 if( clipAreaImpl( aDestRange
,
1736 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1737 assertImageRange(aSrcRange
,aSrcBounds
);
1739 if( isCompatibleClipMask( rClip
) )
1741 drawMaskedBitmap_i( rSrcBitmap
, rMask
, aSrcRange
, aDestRange
, drawMode
, rClip
);
1745 getGenericRenderer()->drawMaskedBitmap( rSrcBitmap
, rMask
, rSrcRect
,
1746 rDstRect
, drawMode
, rClip
);
1753 /** Standard clip and alpha masks
1757 typedef PixelFormatTraits_GREY1_MSB clipmask_format_traits
;
1758 typedef PixelFormatTraits_GREY8 alphamask_format_traits
;
1760 /// Clipmask: 0 means opaque
1761 static const bool clipmask_polarity
= false;
1763 /// Alpha mask: 0 means fully transparent
1764 static const bool alphamask_polarity
= true;
1768 // Some compilers don't like the nested template wrap_accessor
1769 // reference in the parameter list - being slightly less type safe,
1771 #ifndef BASEBMP_NO_NESTED_TEMPLATE_PARAMETER
1773 /// Produces a specialized renderer for the given pixel format
1774 template< class FormatTraits
, class MaskTraits
>
1775 BitmapDeviceSharedPtr
createRenderer(
1776 const basegfx::B2IBox
& rBounds
,
1777 const basegfx::B2IVector
& rBufferSize
,
1778 Format nScanlineFormat
,
1779 sal_Int32 nScanlineStride
,
1780 sal_uInt8
* pFirstScanline
,
1781 typename
FormatTraits::raw_accessor_type
const& rRawAccessor
,
1782 typename
FormatTraits::accessor_selector::template wrap_accessor
<
1783 typename
FormatTraits::raw_accessor_type
>::type
const& rAccessor
,
1784 boost::shared_array
< sal_uInt8
> pMem
,
1785 const PaletteMemorySharedVector
& pPal
,
1786 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1789 template< class FormatTraits
, class MaskTraits
, class Accessor
>
1790 BitmapDeviceSharedPtr
createRenderer(
1791 const basegfx::B2IBox
& rBounds
,
1792 const basegfx::B2IVector
& rBufferSize
,
1793 Format nScanlineFormat
,
1794 sal_Int32 nScanlineStride
,
1795 sal_uInt8
* pFirstScanline
,
1796 typename
FormatTraits::raw_accessor_type
const& rRawAccessor
,
1797 Accessor
const& rAccessor
,
1798 boost::shared_array
< sal_uInt8
> pMem
,
1799 const PaletteMemorySharedVector
& pPal
,
1800 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1804 typedef typename
FormatTraits::iterator_type Iterator
;
1805 typedef BitmapRenderer
< Iterator
,
1806 typename
FormatTraits::raw_accessor_type
,
1807 typename
FormatTraits::accessor_selector
,
1808 MaskTraits
> Renderer
;
1810 return BitmapDeviceSharedPtr(
1811 new Renderer( rBounds
,
1817 reinterpret_cast<typename
Iterator::value_type
*>(
1827 /// Create standard grey level palette
1828 PaletteMemorySharedVector
createStandardPalette(
1829 const PaletteMemorySharedVector
& pPal
,
1830 sal_Int32 nNumEntries
)
1832 if( pPal
|| nNumEntries
<= 0 )
1835 boost::shared_ptr
< std::vector
<Color
> > pLocalPal(
1836 new std::vector
<Color
>(nNumEntries
) );
1838 const sal_Int32
nIncrement( 0x00FFFFFF/nNumEntries
);
1840 for( sal_Int32 i
=0, c
=0; i
<nNumEntries
; ++i
,c
+=nIncrement
)
1841 pLocalPal
->at(i
) = Color(0xFF000000 | c
);
1843 pLocalPal
->at(nNumEntries
) = Color(0xFFFFFFFF);
1848 template< class FormatTraits
, class MaskTraits
>
1849 BitmapDeviceSharedPtr
createRenderer(
1850 const basegfx::B2IBox
& rBounds
,
1851 const basegfx::B2IVector
& rBufferSize
,
1852 Format nScanlineFormat
,
1853 sal_Int32 nScanlineStride
,
1854 sal_uInt8
* pFirstScanline
,
1855 boost::shared_array
< sal_uInt8
> pMem
,
1856 const PaletteMemorySharedVector
& pPal
,
1857 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1859 return createRenderer
<FormatTraits
,
1860 MaskTraits
>(rBounds
,
1865 typename
FormatTraits::raw_accessor_type(),
1866 typename
FormatTraits::accessor_selector::template
1868 typename
FormatTraits::raw_accessor_type
>::type(),
1874 template< class FormatTraits
, class MaskTraits
>
1875 BitmapDeviceSharedPtr
createRenderer(
1876 const basegfx::B2IBox
& rBounds
,
1877 const basegfx::B2IVector
& rBufferSize
,
1878 Format nScanlineFormat
,
1879 sal_Int32 nScanlineStride
,
1880 sal_uInt8
* pFirstScanline
,
1881 boost::shared_array
< sal_uInt8
> pMem
,
1882 PaletteMemorySharedVector pPal
,
1884 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1886 pPal
= createStandardPalette(pPal
,
1887 1UL << nBitsPerPixel
);
1890 return createRenderer
<FormatTraits
,
1891 MaskTraits
>(rBounds
,
1896 typename
FormatTraits::raw_accessor_type(),
1897 typename
FormatTraits::accessor_selector::template
1899 typename
FormatTraits::raw_accessor_type
>::type(
1908 // TODO(Q3): consolidate with canvas/canvastools.hxx! Best move this
1909 // to o3tl or sal/bithacks.hxx ...
1911 /** Compute the next highest power of 2 of a 32-bit value
1913 Code devised by Sean Anderson, in good ole HAKMEM
1916 @return 1 << (lg(x - 1) + 1)
1918 inline sal_uInt32
nextPow2( sal_uInt32 x
)
1935 BitmapDeviceSharedPtr
createBitmapDeviceImplInner( const basegfx::B2IVector
& rSize
,
1937 Format nScanlineFormat
,
1938 boost::shared_array
< sal_uInt8
> pMem
,
1939 PaletteMemorySharedVector pPal
,
1940 const basegfx::B2IBox
* pSubset
,
1941 const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
)
1943 OSL_ASSERT(rSize
.getX() > 0 && rSize
.getY() > 0);
1945 if( nScanlineFormat
<= FORMAT_NONE
||
1946 nScanlineFormat
> FORMAT_MAX
)
1947 return BitmapDeviceSharedPtr();
1951 sal_Int32
nScanlineStride(0);
1953 // round up to full 8 bit, divide by 8
1954 nScanlineStride
= (rSize
.getX()*bitsPerPixel
[nScanlineFormat
] + 7) >> 3;
1956 // rounded up to next full power-of-two number of bytes
1957 const sal_uInt32 bytesPerPixel
= nextPow2(
1958 (bitsPerPixel
[nScanlineFormat
] + 7) >> 3);
1960 // now make nScanlineStride a multiple of bytesPerPixel
1961 nScanlineStride
= (nScanlineStride
+ bytesPerPixel
- 1) / bytesPerPixel
* bytesPerPixel
;
1963 // factor in bottom-up scanline order case
1964 nScanlineStride
*= bTopDown
? 1 : -1;
1966 const sal_uInt32
nWidth(nScanlineStride
< 0 ? -nScanlineStride
: nScanlineStride
);
1967 const sal_uInt32
nHeight(rSize
.getY());
1969 if (nHeight
&& nWidth
&& nWidth
> SAL_MAX_INT32
/ nHeight
)
1971 SAL_WARN( "basebmp", "suspicious massive alloc " << nWidth
<< " * " << nHeight
);
1972 return BitmapDeviceSharedPtr();
1975 const std::size_t nMemSize(nWidth
* nHeight
);
1980 reinterpret_cast<sal_uInt8
*>(rtl_allocateMemory( nMemSize
)),
1982 if (pMem
.get() == 0 && nMemSize
!= 0)
1983 return BitmapDeviceSharedPtr();
1984 memset(pMem
.get(), 0, nMemSize
);
1987 sal_uInt8
* pFirstScanline
= nScanlineStride
< 0 ?
1988 pMem
.get() + nMemSize
+ nScanlineStride
: pMem
.get();
1990 // shrink render area to given subset, if given
1991 basegfx::B2IBox
aBounds(0,0,rSize
.getX(),rSize
.getY());
1993 aBounds
.intersect( *pSubset
);
1995 switch( nScanlineFormat
)
1997 // ----------------------------------------------------------------------
2000 case FORMAT_ONE_BIT_MSB_GREY
:
2001 return createRenderer
<PixelFormatTraits_GREY1_MSB
,StdMasks
>(
2002 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2003 pFirstScanline
, pMem
, pPal
, rDamage
);
2005 case FORMAT_ONE_BIT_LSB_GREY
:
2006 return createRenderer
<PixelFormatTraits_GREY1_LSB
,StdMasks
>(
2007 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2008 pFirstScanline
, pMem
, pPal
, rDamage
);
2010 case FORMAT_ONE_BIT_MSB_PAL
:
2011 return createRenderer
<PixelFormatTraits_PAL1_MSB
,StdMasks
>(
2012 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2013 pFirstScanline
, pMem
, pPal
,
2014 bitsPerPixel
[nScanlineFormat
], rDamage
);
2016 case FORMAT_ONE_BIT_LSB_PAL
:
2017 return createRenderer
<PixelFormatTraits_PAL1_LSB
,StdMasks
>(
2018 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2019 pFirstScanline
, pMem
, pPal
,
2020 bitsPerPixel
[nScanlineFormat
], rDamage
);
2023 // ----------------------------------------------------------------------
2026 case FORMAT_FOUR_BIT_MSB_GREY
:
2027 return createRenderer
<PixelFormatTraits_GREY4_MSB
,StdMasks
>(
2028 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2029 pFirstScanline
, pMem
, pPal
, rDamage
);
2031 case FORMAT_FOUR_BIT_LSB_GREY
:
2032 return createRenderer
<PixelFormatTraits_GREY4_LSB
,StdMasks
>(
2033 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2034 pFirstScanline
, pMem
, pPal
, rDamage
);
2036 case FORMAT_FOUR_BIT_MSB_PAL
:
2037 return createRenderer
<PixelFormatTraits_PAL4_MSB
,StdMasks
>(
2038 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2039 pFirstScanline
, pMem
, pPal
,
2040 bitsPerPixel
[nScanlineFormat
], rDamage
);
2042 case FORMAT_FOUR_BIT_LSB_PAL
:
2043 return createRenderer
<PixelFormatTraits_PAL4_LSB
,StdMasks
>(
2044 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2045 pFirstScanline
, pMem
, pPal
,
2046 bitsPerPixel
[nScanlineFormat
], rDamage
);
2049 // ----------------------------------------------------------------------
2050 // eight bit formats
2052 case FORMAT_EIGHT_BIT_GREY
:
2053 return createRenderer
<PixelFormatTraits_GREY8
,StdMasks
>(
2054 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2055 pFirstScanline
, pMem
, pPal
, rDamage
);
2057 case FORMAT_EIGHT_BIT_PAL
:
2058 return createRenderer
<PixelFormatTraits_PAL8
,StdMasks
>(
2059 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2060 pFirstScanline
, pMem
, pPal
,
2061 bitsPerPixel
[nScanlineFormat
], rDamage
);
2064 // ----------------------------------------------------------------------
2065 // sixteen bit formats
2067 case FORMAT_SIXTEEN_BIT_LSB_TC_MASK
:
2068 return createRenderer
<PixelFormatTraits_RGB16_565_LSB
,StdMasks
>(
2069 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2070 pFirstScanline
, pMem
, pPal
, rDamage
);
2072 case FORMAT_SIXTEEN_BIT_MSB_TC_MASK
:
2073 return createRenderer
<PixelFormatTraits_RGB16_565_MSB
,StdMasks
>(
2074 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2075 pFirstScanline
, pMem
, pPal
, rDamage
);
2078 // ----------------------------------------------------------------------
2079 // twentyfour bit formats
2080 case FORMAT_TWENTYFOUR_BIT_TC_MASK
:
2081 return createRenderer
<PixelFormatTraits_BGR24
,StdMasks
>(
2082 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2083 pFirstScanline
, pMem
, pPal
, rDamage
);
2086 // ----------------------------------------------------------------------
2087 // thirtytwo bit formats
2089 case FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA
:
2090 return createRenderer
<PixelFormatTraits_BGRX32_8888
,StdMasks
>(
2091 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2092 pFirstScanline
, pMem
, pPal
, rDamage
);
2094 case FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB
:
2095 return createRenderer
<PixelFormatTraits_XRGB32_8888
,StdMasks
>(
2096 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2097 pFirstScanline
, pMem
, pPal
, rDamage
);
2099 case FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR
:
2100 return createRenderer
<PixelFormatTraits_XBGR32_8888
,StdMasks
>(
2101 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2102 pFirstScanline
, pMem
, pPal
, rDamage
);
2104 case FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA
:
2105 return createRenderer
<PixelFormatTraits_RGBX32_8888
,StdMasks
>(
2106 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2107 pFirstScanline
, pMem
, pPal
, rDamage
);
2110 assert(false); // this cannot happen
2113 // TODO(F3): other formats not yet implemented
2114 return BitmapDeviceSharedPtr();
2117 BitmapDeviceSharedPtr
createBitmapDeviceImpl( const basegfx::B2IVector
& rSize
,
2119 Format nScanlineFormat
,
2120 boost::shared_array
< sal_uInt8
> pMem
,
2121 PaletteMemorySharedVector pPal
,
2122 const basegfx::B2IBox
* pSubset
,
2123 const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
)
2125 BitmapDeviceSharedPtr
result( createBitmapDeviceImplInner( rSize
, bTopDown
, nScanlineFormat
, pMem
, pPal
, pSubset
, rDamage
) );
2128 std::ostringstream subset
;
2131 subset
<< " subset=" << pSubset
->getWidth() << "x" << pSubset
->getHeight() << "@(" << pSubset
->getMinX() << "," << pSubset
->getMinY() << ")";
2133 SAL_INFO( "basebmp.bitmapdevice",
2134 "createBitmapDevice: "
2135 << rSize
.getX() << "x" << rSize
.getY()
2136 << (bTopDown
? " top-down " : " bottom-up ")
2137 << formatName(nScanlineFormat
)
2139 << " = " << result
.get() );
2146 BitmapDeviceSharedPtr
createBitmapDevice( const basegfx::B2IVector
& rSize
,
2148 Format nScanlineFormat
)
2150 return createBitmapDeviceImpl( rSize
,
2153 boost::shared_array
< sal_uInt8
>(),
2154 PaletteMemorySharedVector(),
2156 IBitmapDeviceDamageTrackerSharedPtr() );
2159 BitmapDeviceSharedPtr
createBitmapDevice( const basegfx::B2IVector
& rSize
,
2161 Format nScanlineFormat
,
2162 const PaletteMemorySharedVector
& rPalette
)
2164 return createBitmapDeviceImpl( rSize
,
2167 boost::shared_array
< sal_uInt8
>(),
2170 IBitmapDeviceDamageTrackerSharedPtr() );
2173 BitmapDeviceSharedPtr
createBitmapDevice( const basegfx::B2IVector
& rSize
,
2175 Format nScanlineFormat
,
2176 const RawMemorySharedArray
& rMem
,
2177 const PaletteMemorySharedVector
& rPalette
)
2179 return createBitmapDeviceImpl( rSize
,
2185 IBitmapDeviceDamageTrackerSharedPtr() );
2188 BitmapDeviceSharedPtr
subsetBitmapDevice( const BitmapDeviceSharedPtr
& rProto
,
2189 const basegfx::B2IBox
& rSubset
)
2191 SAL_INFO( "basebmp.bitmapdevice", "subsetBitmapDevice: proto=" << rProto
.get() );
2192 return createBitmapDeviceImpl( rProto
->getSize(),
2193 rProto
->isTopDown(),
2194 rProto
->getScanlineFormat(),
2195 rProto
->getBuffer(),
2196 rProto
->getPalette(),
2198 rProto
->getDamageTracker() );
2201 BitmapDeviceSharedPtr
cloneBitmapDevice( const basegfx::B2IVector
& rSize
,
2202 const BitmapDeviceSharedPtr
& rProto
)
2204 return createBitmapDeviceImpl( rSize
,
2205 rProto
->isTopDown(),
2206 rProto
->getScanlineFormat(),
2207 boost::shared_array
< sal_uInt8
>(),
2208 rProto
->getPalette(),
2210 rProto
->getDamageTracker() );
2214 /// Clone our device, with GenericImageAccessor to handle all formats
2215 BitmapDeviceSharedPtr
BitmapDevice::getGenericRenderer() const
2217 return mpImpl
->mpGenericRenderer
;
2220 } // namespace basebmp
2222 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */