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 <sal/log.hxx>
56 #include <osl/diagnose.h>
58 #include <basegfx/tools/tools.hxx>
59 #include <basegfx/tools/canvastools.hxx>
60 #include <basegfx/range/b2ibox.hxx>
61 #include <basegfx/range/b2irange.hxx>
62 #include <basegfx/range/b2drange.hxx>
63 #include <basegfx/polygon/b2dpolygon.hxx>
64 #include <basegfx/polygon/b2dpolygontools.hxx>
65 #include <basegfx/polygon/b2dpolypolygontools.hxx>
66 #include <basegfx/point/b2ipoint.hxx>
67 #include <basegfx/vector/b2ivector.hxx>
69 #include <vigra/iteratortraits.hxx>
70 #include <vigra/rgbvalue.hxx>
71 #include <vigra/copyimage.hxx>
72 #include <vigra/tuple.hxx>
78 /// componentwise xor of an RGBValue (missing from rgbvalue.hxx)
79 template< class Value
, unsigned int RedIndex
, unsigned int BlueIndex
, unsigned int GreenIndex
>
80 inline RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
>
81 operator^( RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
> const& lhs
,
82 RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
> const& rhs
)
84 RGBValue
<Value
, RedIndex
, GreenIndex
, BlueIndex
> res(
95 static const sal_uInt8 bitsPerPixel
[] =
98 1, // ONE_BIT_MSB_GREY
99 1, // ONE_BIT_LSB_GREY
100 1, // ONE_BIT_MSB_PAL
101 1, // ONE_BIT_LSB_PAL
102 4, // FOUR_BIT_MSB_GREY
103 4, // FOUR_BIT_LSB_GREY
104 4, // FOUR_BIT_MSB_PAL
105 4, // FOUR_BIT_LSB_PAL
108 16, // SIXTEEN_BIT_LSB_TC_MASK
109 16, // SIXTEEN_BIT_MSB_TC_MASK
110 24, // TWENTYFOUR_BIT_TC_MASK
111 32, // TWENTYFOUR_BIT_TC_MASK_BGRX
112 32, // THIRTYTWO_BIT_TC_MASK_BGRA
113 32, // THIRTYTWO_BIT_TC_MASK_ARGB
114 32, // THIRTYTWO_BIT_TC_MASK_ABGR
115 32, // THIRTYTWO_BIT_TC_MASK_RGBA
120 /** Create the type for an accessor that takes the (mask,bitmap)
121 input value generated from a JoinImageAccessorAdapter, and
122 pipe that through a mask functor.
125 Destination bitmap accessor
128 Input accessor, is expected to generate a std::pair as the
132 Either FastMask or NoFastMask, depending on whether the mask
133 is guaranteed to contain only 0s and 1s.
135 template< class DestAccessor
,
136 class JoinedAccessor
,
138 typename MaskFunctorMode
> struct masked_input_splitting_accessor
140 typedef BinarySetterFunctionAccessorAdapter
<
142 BinaryFunctorSplittingWrapper
<
143 typename outputMaskFunctorSelector
<
144 typename
JoinedAccessor::value_type::first_type
,
145 typename
JoinedAccessor::value_type::second_type
,
147 MaskFunctorMode
>::type
> > type
;
152 // Actual BitmapDevice implementation (templatized by accessor and iterator)
154 /** Implementation of the BitmapDevice interface
157 Iterator to access bitmap memory
160 Raw accessor, to access pixel values directly
162 @tpl AccessorSelector
163 Accessor adapter selector, which, when applying the nested
164 template metafunction wrap_accessor to one of the raw bitmap
165 accessors, yields a member type named 'type', which is a
166 wrapped accessor that map color values.
169 Traits template, containing nested traits
170 clipmask_format_traits and alphamask_format_traits, which
171 determine what specialized formats are to be used for clip and
172 alpha masks. With those mask formats, clipping and alpha
173 blending is handled natively.
175 template< class DestIterator
,
177 class AccessorSelector
,
178 class Masks
> class BitmapRenderer
:
182 typedef DestIterator dest_iterator_type
;
183 typedef RawAccessor raw_accessor_type
;
184 typedef AccessorSelector accessor_selector
;
186 typedef typename
Masks::clipmask_format_traits::iterator_type mask_iterator_type
;
187 typedef typename
Masks::clipmask_format_traits::raw_accessor_type mask_rawaccessor_type
;
188 typedef typename
Masks::clipmask_format_traits::accessor_selector mask_accessorselector_type
;
190 typedef typename
Masks::alphamask_format_traits::iterator_type alphamask_iterator_type
;
191 typedef typename
Masks::alphamask_format_traits::raw_accessor_type alphamask_rawaccessor_type
;
192 typedef typename
Masks::alphamask_format_traits::accessor_selector alphamask_accessorselector_type
;
194 typedef typename
AccessorSelector::template wrap_accessor
<
195 raw_accessor_type
>::type dest_accessor_type
;
197 typedef AccessorTraits
< dest_accessor_type
> accessor_traits
;
198 typedef CompositeIterator2D
< dest_iterator_type
,
199 mask_iterator_type
> composite_iterator_type
;
200 typedef CompositeIterator2D
< vigra::Diff2D
,
201 vigra::Diff2D
> generic_composite_iterator_type
;
203 typedef BitmapRenderer
<mask_iterator_type
,
204 mask_rawaccessor_type
,
205 mask_accessorselector_type
,
206 Masks
> mask_bitmap_type
;
207 typedef BitmapRenderer
<alphamask_iterator_type
,
208 alphamask_rawaccessor_type
,
209 alphamask_accessorselector_type
,
210 Masks
> alphamask_bitmap_type
;
214 typedef AccessorTraits
< raw_accessor_type
> raw_accessor_traits
;
215 typedef typename uInt32Converter
<
216 typename
raw_accessor_type::value_type
>::to to_uint32_functor
;
220 typedef typename
raw_accessor_traits::xor_accessor raw_xor_accessor_type
;
221 typedef AccessorTraits
<raw_xor_accessor_type
> raw_xor_accessor_traits
;
222 typedef typename
accessor_selector::template wrap_accessor
<
223 raw_xor_accessor_type
>::type xor_accessor_type
;
224 typedef AccessorTraits
<xor_accessor_type
> xor_accessor_traits
;
228 typedef typename
raw_accessor_traits::template masked_accessor
<
229 mask_rawaccessor_type
,
232 Masks::clipmask_polarity
>::type raw_maskedaccessor_type
;
233 typedef typename
accessor_selector::template wrap_accessor
<
234 raw_maskedaccessor_type
>::type masked_accessor_type
;
235 typedef typename AccessorTraits
<
236 raw_maskedaccessor_type
>::xor_accessor raw_maskedxor_accessor_type
;
237 typedef typename
accessor_selector::template wrap_accessor
<
238 raw_maskedxor_accessor_type
>::type masked_xoraccessor_type
;
242 // ((iter,mask),mask) special case (e.g. for clipped
243 // drawMaskedColor())
244 typedef AccessorTraits
< raw_maskedaccessor_type
> raw_maskedaccessor_traits
;
245 typedef typename
raw_maskedaccessor_traits::template masked_accessor
<
246 mask_rawaccessor_type
,
247 composite_iterator_type
,
249 Masks::clipmask_polarity
>::type raw_maskedmask_accessor_type
;
251 typedef CompositeIterator2D
<
252 composite_iterator_type
,
253 mask_iterator_type
> composite_composite_mask_iterator_type
;
257 typedef ConstantColorBlendSetterAccessorAdapter
<
259 typename
alphamask_rawaccessor_type::value_type
,
260 Masks::alphamask_polarity
> colorblend_accessor_type
;
261 typedef AccessorTraits
<colorblend_accessor_type
> colorblend_accessor_traits
;
262 typedef typename
colorblend_accessor_traits::template masked_accessor
<
263 mask_rawaccessor_type
,
266 Masks::clipmask_polarity
>::type masked_colorblend_accessor_type
;
270 typedef ConstantColorBlendSetterAccessorAdapter
<
273 Masks::alphamask_polarity
> colorblend_generic_accessor_type
;
274 typedef AccessorTraits
<colorblend_generic_accessor_type
> colorblend_generic_accessor_traits
;
275 typedef typename
colorblend_generic_accessor_traits::template masked_accessor
<
276 mask_rawaccessor_type
,
279 Masks::clipmask_polarity
>::type masked_colorblend_generic_accessor_type
;
283 typedef JoinImageAccessorAdapter
< dest_accessor_type
,
284 mask_rawaccessor_type
> joined_image_accessor_type
;
285 typedef JoinImageAccessorAdapter
< GenericColorImageAccessor
,
286 GenericColorImageAccessor
> joined_generic_image_accessor_type
;
290 dest_iterator_type maBegin
;
291 typename
accessor_traits::color_lookup maColorLookup
;
292 IBitmapDeviceDamageTrackerSharedPtr mpDamage
;
293 to_uint32_functor maToUInt32Converter
;
294 dest_accessor_type maAccessor
;
295 colorblend_accessor_type maColorBlendAccessor
;
296 colorblend_generic_accessor_type maGenericColorBlendAccessor
;
297 raw_accessor_type maRawAccessor
;
298 xor_accessor_type maXorAccessor
;
299 raw_xor_accessor_type maRawXorAccessor
;
300 masked_accessor_type maMaskedAccessor
;
301 masked_colorblend_accessor_type maMaskedColorBlendAccessor
;
302 masked_colorblend_generic_accessor_type maGenericMaskedColorBlendAccessor
;
303 masked_xoraccessor_type maMaskedXorAccessor
;
304 raw_maskedaccessor_type maRawMaskedAccessor
;
305 raw_maskedxor_accessor_type maRawMaskedXorAccessor
;
306 raw_maskedmask_accessor_type maRawMaskedMaskAccessor
;
311 BitmapRenderer( const basegfx::B2IBox
& rBounds
,
312 const basegfx::B2IVector
& rBufferSize
,
313 Format nScanlineFormat
,
314 sal_Int32 nScanlineStride
,
315 sal_uInt8
* pFirstScanline
,
316 dest_iterator_type begin
,
317 raw_accessor_type rawAccessor
,
318 dest_accessor_type accessor
,
319 const RawMemorySharedArray
& rMem
,
320 const PaletteMemorySharedVector
& rPalette
,
321 const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
) :
322 BitmapDevice( rBounds
, rBufferSize
, nScanlineFormat
,
323 nScanlineStride
, pFirstScanline
, rMem
, rPalette
),
327 maToUInt32Converter(),
328 maAccessor( accessor
),
329 maColorBlendAccessor( accessor
),
330 maGenericColorBlendAccessor( accessor
),
331 maRawAccessor( rawAccessor
),
332 maXorAccessor( accessor
),
333 maRawXorAccessor( rawAccessor
),
334 maMaskedAccessor( accessor
),
335 maMaskedColorBlendAccessor( maColorBlendAccessor
),
336 maGenericMaskedColorBlendAccessor( maGenericColorBlendAccessor
),
337 maMaskedXorAccessor( accessor
),
338 maRawMaskedAccessor( rawAccessor
),
339 maRawMaskedXorAccessor( rawAccessor
),
340 maRawMaskedMaskAccessor( rawAccessor
)
345 void damaged( const basegfx::B2IBox
& rDamageRect
) const
348 mpDamage
->damaged( rDamageRect
);
351 void damagedPointSize( const basegfx::B2IPoint
& rPoint
,
352 const basegfx::B2IBox
& rSize
) const
355 basegfx::B2IPoint
aLower( rPoint
.getX() + rSize
.getWidth(),
356 rPoint
.getY() + rSize
.getHeight() );
357 damaged( basegfx::B2IBox( rPoint
, aLower
) );
361 void damagedPixel( const basegfx::B2IPoint
& rDamagePoint
) const
366 sal_Int32
nX(rDamagePoint
.getX());
367 sal_Int32
nY(rDamagePoint
.getY());
368 if (nX
< SAL_MAX_INT32
)
370 if (nY
< SAL_MAX_INT32
)
373 basegfx::B2IPoint
aEnd( nX
, nY
);
374 damaged( basegfx::B2IBox( rDamagePoint
, aEnd
) );
377 static boost::shared_ptr
<BitmapRenderer
> getCompatibleBitmap( const BitmapDeviceSharedPtr
& bmp
)
379 return boost::dynamic_pointer_cast
< BitmapRenderer
>( bmp
);
382 virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr
& bmp
) const SAL_OVERRIDE
384 // TODO(P1): dynamic_cast usually called twice for
385 // compatible formats
386 return getCompatibleBitmap(bmp
).get() != NULL
;
389 boost::shared_ptr
<mask_bitmap_type
> getCompatibleClipMask( const BitmapDeviceSharedPtr
& bmp
) const
391 boost::shared_ptr
<mask_bitmap_type
> pMask( boost::dynamic_pointer_cast
<mask_bitmap_type
>( bmp
));
396 if( pMask
->getSize() != getSize() )
402 virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr
& bmp
) const SAL_OVERRIDE
404 // TODO(P1): dynamic_cast usually called twice for
405 // compatible formats
406 return boost::dynamic_pointer_cast
<mask_bitmap_type
>( bmp
).get() != NULL
;
409 static boost::shared_ptr
<alphamask_bitmap_type
> getCompatibleAlphaMask( const BitmapDeviceSharedPtr
& bmp
)
411 return boost::dynamic_pointer_cast
<alphamask_bitmap_type
>( bmp
);
414 virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr
& bmp
) const SAL_OVERRIDE
416 // TODO(P1): dynamic_cast usually called twice for
417 // compatible formats
418 return getCompatibleAlphaMask( bmp
).get() != NULL
;
421 virtual void clear_i( Color fillColor
,
422 const basegfx::B2IBox
& rBounds
) SAL_OVERRIDE
424 fillImage(destIterRange(maBegin
,
433 virtual void setPixel_i( const basegfx::B2IPoint
& rPt
,
435 DrawMode drawMode
) SAL_OVERRIDE
437 const DestIterator
pixel( maBegin
+
438 vigra::Diff2D(rPt
.getX(),
440 if( drawMode
== DrawMode_XOR
)
441 maXorAccessor
.set( pixelColor
,
444 maAccessor
.set( pixelColor
,
449 virtual void setPixel_i( const basegfx::B2IPoint
& rPt
,
452 const BitmapDeviceSharedPtr
& rClip
) SAL_OVERRIDE
454 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rClip
) );
457 const vigra::Diff2D
offset(rPt
.getX(),
460 const composite_iterator_type
aIter(
462 pMask
->maBegin
+ offset
);
464 if( drawMode
== DrawMode_XOR
)
465 maMaskedXorAccessor
.set( pixelColor
,
468 maMaskedAccessor
.set( pixelColor
,
473 virtual Color
getPixel_i(const basegfx::B2IPoint
& rPt
) SAL_OVERRIDE
475 const DestIterator
pixel( maBegin
+
476 vigra::Diff2D(rPt
.getX(),
478 return maAccessor(pixel
);
481 virtual sal_uInt32
getPixelData_i( const basegfx::B2IPoint
& rPt
) SAL_OVERRIDE
483 const DestIterator
pixel( maBegin
+
484 vigra::Diff2D(rPt
.getX(),
486 return maToUInt32Converter(maRawAccessor(pixel
));
489 template< typename Iterator
, typename Col
, typename RawAcc
>
490 void implRenderLine2( const basegfx::B2IPoint
& rPt1
,
491 const basegfx::B2IPoint
& rPt2
,
492 const basegfx::B2IBox
& rBounds
,
494 const Iterator
& begin
,
495 const RawAcc
& rawAcc
)
497 renderClippedLine( rPt1
,
507 // TODO(P2): perhaps this needs pushing up the stack a bit
508 // to make more complex polygons more efficient ...
509 basegfx::B2IBox
aBounds(rPt1
, rPt2
);
511 const basegfx::B2IPoint
& rEnd
= aBounds
.getMaximum();
513 sal_Int32
nX(rEnd
.getX());
514 sal_Int32
nY(rEnd
.getY());
515 if (nX
< SAL_MAX_INT32
)
517 if (nY
< SAL_MAX_INT32
)
520 basegfx::B2IBox
aDamagedBox(aBounds
.getMinimum(), basegfx::B2IPoint(nX
, nY
));
521 damaged(aDamagedBox
);
524 template< typename Iterator
, typename Accessor
, typename RawAcc
>
525 void implRenderLine( const basegfx::B2IPoint
& rPt1
,
526 const basegfx::B2IPoint
& rPt2
,
527 const basegfx::B2IBox
& rBounds
,
529 const Iterator
& begin
,
531 const RawAcc
& rawAcc
)
533 implRenderLine2( rPt1
,rPt2
,rBounds
,
540 template< typename Iterator
, typename RawAcc
, typename XorAcc
>
541 void implDrawLine( const basegfx::B2IPoint
& rPt1
,
542 const basegfx::B2IPoint
& rPt2
,
543 const basegfx::B2IBox
& rBounds
,
545 const Iterator
& begin
,
546 const RawAcc
& rawAcc
,
547 const XorAcc
& xorAcc
,
550 if( drawMode
== DrawMode_XOR
)
551 implRenderLine( rPt1
, rPt2
, rBounds
, col
,
552 begin
, maAccessor
, xorAcc
);
554 implRenderLine( rPt1
, rPt2
, rBounds
, col
,
555 begin
, maAccessor
, rawAcc
);
558 virtual void drawLine_i(const basegfx::B2IPoint
& rPt1
,
559 const basegfx::B2IPoint
& rPt2
,
560 const basegfx::B2IBox
& rBounds
,
562 DrawMode drawMode
) SAL_OVERRIDE
564 implDrawLine(rPt1
,rPt2
,rBounds
,lineColor
,
566 maRawAccessor
,maRawXorAccessor
,drawMode
);
569 composite_iterator_type
getMaskedIter( const BitmapDeviceSharedPtr
& rClip
) const
571 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rClip
) );
574 return composite_iterator_type( maBegin
,
578 virtual void drawLine_i(const basegfx::B2IPoint
& rPt1
,
579 const basegfx::B2IPoint
& rPt2
,
580 const basegfx::B2IBox
& rBounds
,
583 const BitmapDeviceSharedPtr
& rClip
) SAL_OVERRIDE
585 implDrawLine(rPt1
,rPt2
,rBounds
,lineColor
,
586 getMaskedIter(rClip
),
588 maRawMaskedXorAccessor
,drawMode
);
591 template< typename Iterator
, typename RawAcc
>
592 void implDrawPolygon( const basegfx::B2DPolygon
& rPoly
,
593 const basegfx::B2IBox
& rBounds
,
595 const Iterator
& begin
,
598 basegfx::B2DPolygon
aPoly( rPoly
);
599 if( rPoly
.areControlPointsUsed() )
600 aPoly
= basegfx::tools::adaptiveSubdivideByCount( rPoly
);
602 const typename
dest_iterator_type::value_type
colorIndex( maColorLookup(
605 const sal_uInt32
nVertices( aPoly
.count() );
606 for( sal_uInt32 i
=1; i
<nVertices
; ++i
)
607 implRenderLine2( basegfx::fround(aPoly
.getB2DPoint(i
-1)),
608 basegfx::fround(aPoly
.getB2DPoint(i
)),
614 if( nVertices
> 1 && aPoly
.isClosed() )
615 implRenderLine2( basegfx::fround(aPoly
.getB2DPoint(nVertices
-1)),
616 basegfx::fround(aPoly
.getB2DPoint(0)),
623 virtual void drawPolygon_i(const basegfx::B2DPolygon
& rPoly
,
624 const basegfx::B2IBox
& rBounds
,
626 DrawMode drawMode
) SAL_OVERRIDE
628 if( drawMode
== DrawMode_XOR
)
629 implDrawPolygon( rPoly
, rBounds
, lineColor
,
633 implDrawPolygon( rPoly
, rBounds
, lineColor
,
638 virtual void drawPolygon_i(const basegfx::B2DPolygon
& rPoly
,
639 const basegfx::B2IBox
& rBounds
,
642 const BitmapDeviceSharedPtr
& rClip
) SAL_OVERRIDE
644 if( drawMode
== DrawMode_XOR
)
645 implDrawPolygon( rPoly
, rBounds
, lineColor
,
646 getMaskedIter(rClip
),
647 maRawMaskedXorAccessor
);
649 implDrawPolygon( rPoly
, rBounds
, lineColor
,
650 getMaskedIter(rClip
),
651 maRawMaskedAccessor
);
654 template< typename Iterator
, typename RawAcc
>
655 void implFillPolyPolygon( const basegfx::B2DPolyPolygon
& rPoly
,
657 const Iterator
& begin
,
659 const basegfx::B2IBox
& rBounds
)
661 basegfx::B2DPolyPolygon
aPoly( rPoly
);
662 if( rPoly
.areControlPointsUsed() )
663 aPoly
= basegfx::tools::adaptiveSubdivideByCount( rPoly
);
665 renderClippedPolyPolygon( begin
,
667 maColorLookup( maAccessor
,
671 basegfx::FillRule_EVEN_ODD
);
675 basegfx::B2DRange
const aPolyBounds( basegfx::tools::getRange(aPoly
) );
676 damaged( basegfx::unotools::b2ISurroundingBoxFromB2DRange( aPolyBounds
) );
680 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon
& rPoly
,
683 const basegfx::B2IBox
& rBounds
) SAL_OVERRIDE
685 if( drawMode
== DrawMode_XOR
)
686 implFillPolyPolygon( rPoly
, fillColor
,
691 implFillPolyPolygon( rPoly
, fillColor
,
697 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon
& rPoly
,
700 const basegfx::B2IBox
& rBounds
,
701 const BitmapDeviceSharedPtr
& rClip
) SAL_OVERRIDE
703 if( drawMode
== DrawMode_XOR
)
704 implFillPolyPolygon( rPoly
, fillColor
,
705 getMaskedIter(rClip
),
706 maRawMaskedXorAccessor
,
709 implFillPolyPolygon( rPoly
, fillColor
,
710 getMaskedIter(rClip
),
715 template< typename Iterator
, typename RawAcc
>
716 void implDrawBitmap(const BitmapDeviceSharedPtr
& rSrcBitmap
,
717 const basegfx::B2IBox
& rSrcRect
,
718 const basegfx::B2IBox
& rDstRect
,
719 const Iterator
& begin
,
722 boost::shared_ptr
<BitmapRenderer
> pSrcBmp( getCompatibleBitmap(rSrcBitmap
) );
723 OSL_ASSERT( pSrcBmp
);
726 srcIterRange(pSrcBmp
->maBegin
,
727 pSrcBmp
->maRawAccessor
,
732 isSharedBuffer(rSrcBitmap
) );
736 template< typename Iterator
, typename Acc
>
737 void implDrawBitmapGeneric(const BitmapDeviceSharedPtr
& rSrcBitmap
,
738 const basegfx::B2IBox
& rSrcRect
,
739 const basegfx::B2IBox
& rDstRect
,
740 const Iterator
& begin
,
743 GenericColorImageAccessor
aSrcAcc( rSrcBitmap
);
746 srcIterRange(vigra::Diff2D(),
755 void implDrawBitmapDirect(const BitmapDeviceSharedPtr
& rSrcBitmap
,
756 const basegfx::B2IBox
& rSrcRect
,
757 const basegfx::B2IBox
& rDstRect
)
759 sal_Int32 nSrcX
= rSrcRect
.getMinX();
760 sal_Int32 nSrcY
= rSrcRect
.getMinY();
761 sal_Int32 nSrcWidth
= rSrcRect
.getWidth();
762 sal_Int32 nSrcHeight
= rSrcRect
.getHeight();
763 sal_Int32 nDestX
= rDstRect
.getMinX();
764 sal_Int32 nDestY
= rDstRect
.getMinY();
766 char* dstBuf
= reinterpret_cast<char*>(getBuffer().get());
767 char* srcBuf
= reinterpret_cast<char*>(rSrcBitmap
->getBuffer().get());
768 sal_Int32 dstStride
= getScanlineStride();
769 sal_Int32 srcStride
= rSrcBitmap
->getScanlineStride();
770 sal_Int32 bytesPerPixel
= (bitsPerPixel
[getScanlineFormat()] + 7) >> 3; // round up to bytes
771 bool dstTopDown
= isTopDown();
772 bool srcTopDown
= rSrcBitmap
->isTopDown();
774 if (dstBuf
== srcBuf
&& nSrcY
< nDestY
) // reverse copy order to avoid overlapping
776 nSrcY
= getBufferSize().getY() - nSrcY
- nSrcHeight
;
777 nDestY
= getBufferSize().getY() - nDestY
- nSrcHeight
;
778 srcTopDown
= !srcTopDown
;
779 dstTopDown
= !dstTopDown
;
784 dstBuf
+= dstStride
* (getBufferSize().getY() - 1);
785 dstStride
= -dstStride
;
790 srcBuf
+= srcStride
* (rSrcBitmap
->getBufferSize().getY() - 1);
791 srcStride
= -srcStride
;
794 char* dstline
= dstBuf
+ dstStride
* nDestY
+ nDestX
* bytesPerPixel
;
795 char* srcline
= srcBuf
+ srcStride
* nSrcY
+ nSrcX
* bytesPerPixel
;
796 sal_Int32 lineBytes
= nSrcWidth
* bytesPerPixel
;
798 for(; 0 < nSrcHeight
; nSrcHeight
--)
800 memmove(dstline
, srcline
, lineBytes
);
801 dstline
+= dstStride
;
802 srcline
+= srcStride
;
806 virtual void drawBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
807 const basegfx::B2IBox
& rSrcRect
,
808 const basegfx::B2IBox
& rDstRect
,
809 DrawMode drawMode
) SAL_OVERRIDE
811 if( isCompatibleBitmap( rSrcBitmap
) )
813 if( drawMode
== DrawMode_XOR
)
814 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
817 else if (bitsPerPixel
[getScanlineFormat()] >= 8
818 && rSrcRect
.getWidth() == rDstRect
.getWidth() && rSrcRect
.getHeight() == rDstRect
.getHeight()
819 && rSrcBitmap
->getScanlineFormat() == getScanlineFormat())
820 implDrawBitmapDirect(rSrcBitmap
, rSrcRect
, rDstRect
);
822 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
828 if( drawMode
== DrawMode_XOR
)
829 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
833 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
840 virtual void drawBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
841 const basegfx::B2IBox
& rSrcRect
,
842 const basegfx::B2IBox
& rDstRect
,
844 const BitmapDeviceSharedPtr
& rClip
) SAL_OVERRIDE
846 if( isCompatibleBitmap( rSrcBitmap
) )
848 if( drawMode
== DrawMode_XOR
)
849 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
850 getMaskedIter(rClip
),
851 maRawMaskedXorAccessor
);
853 implDrawBitmap(rSrcBitmap
, rSrcRect
, rDstRect
,
854 getMaskedIter(rClip
),
855 maRawMaskedAccessor
);
859 if( drawMode
== DrawMode_XOR
)
860 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
861 getMaskedIter(rClip
),
862 maMaskedXorAccessor
);
864 implDrawBitmapGeneric(rSrcBitmap
, rSrcRect
, rDstRect
,
865 getMaskedIter(rClip
),
871 virtual void drawMaskedColor_i(Color aSrcColor
,
872 const BitmapDeviceSharedPtr
& rAlphaMask
,
873 const basegfx::B2IBox
& rSrcRect
,
874 const basegfx::B2IPoint
& rDstPoint
) SAL_OVERRIDE
876 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rAlphaMask
) );
877 boost::shared_ptr
<alphamask_bitmap_type
> pAlpha( getCompatibleAlphaMask(rAlphaMask
) );
881 maColorBlendAccessor
.setColor( aSrcColor
);
883 vigra::copyImage( srcIterRange(pAlpha
->maBegin
,
884 pAlpha
->maRawAccessor
,
887 maColorBlendAccessor
,
892 const composite_iterator_type
aBegin(
893 maBegin
+ vigra::Diff2D(rDstPoint
.getX(),
895 pMask
->maBegin
+ topLeft(rSrcRect
) );
898 aBegin
+ vigra::Diff2D(rSrcRect
.getWidth(),
899 rSrcRect
.getHeight()),
907 GenericColorImageAccessor
aSrcAcc( rAlphaMask
);
908 maGenericColorBlendAccessor
.setColor( aSrcColor
);
910 vigra::copyImage( srcIterRange(vigra::Diff2D(),
914 maGenericColorBlendAccessor
,
917 damagedPointSize( rDstPoint
, rSrcRect
);
920 virtual void drawMaskedColor_i(Color aSrcColor
,
921 const BitmapDeviceSharedPtr
& rAlphaMask
,
922 const basegfx::B2IBox
& rSrcRect
,
923 const basegfx::B2IPoint
& rDstPoint
,
924 const BitmapDeviceSharedPtr
& rClip
) SAL_OVERRIDE
926 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rAlphaMask
) );
927 boost::shared_ptr
<alphamask_bitmap_type
> pAlpha( getCompatibleAlphaMask(rAlphaMask
) );
931 const composite_iterator_type
aBegin( getMaskedIter(rClip
) );
932 maMaskedColorBlendAccessor
.get1stWrappedAccessor().setColor(
935 vigra::copyImage( srcIterRange(pAlpha
->maBegin
,
936 pAlpha
->maRawAccessor
,
939 maMaskedColorBlendAccessor
,
944 boost::shared_ptr
<mask_bitmap_type
> pClipMask( getCompatibleClipMask(rClip
) );
945 OSL_ASSERT( pClipMask
);
947 // setup a ((iter,mask),clipMask) composite composite
948 // iterator, to pass both masks (clip and alpha mask)
950 const composite_composite_mask_iterator_type
aBegin(
951 composite_iterator_type(
952 maBegin
+ vigra::Diff2D(rDstPoint
.getX(),
954 pMask
->maBegin
+ topLeft(rSrcRect
)),
955 pClipMask
->maBegin
+ vigra::Diff2D(rDstPoint
.getX(),
959 aBegin
+ vigra::Diff2D(rSrcRect
.getWidth(),
960 rSrcRect
.getHeight()),
961 maRawMaskedMaskAccessor
,
968 GenericColorImageAccessor
aSrcAcc( rAlphaMask
);
969 const composite_iterator_type
aBegin( getMaskedIter(rClip
) );
970 maGenericMaskedColorBlendAccessor
.get1stWrappedAccessor().setColor(
973 vigra::copyImage( srcIterRange(vigra::Diff2D(),
977 maGenericMaskedColorBlendAccessor
,
980 damagedPointSize( rDstPoint
, rSrcRect
);
983 template< typename Iterator
, typename Acc
>
984 void implDrawMaskedBitmap(const BitmapDeviceSharedPtr
& rSrcBitmap
,
985 const BitmapDeviceSharedPtr
& rMask
,
986 const basegfx::B2IBox
& rSrcRect
,
987 const basegfx::B2IBox
& rDstRect
,
988 const Iterator
& begin
,
991 boost::shared_ptr
<BitmapRenderer
> pSrcBmp( getCompatibleBitmap(rSrcBitmap
) );
992 boost::shared_ptr
<mask_bitmap_type
> pMask( getCompatibleClipMask(rMask
) );
993 OSL_ASSERT( pMask
&& pSrcBmp
);
996 srcIterRange(composite_iterator_type(
999 joined_image_accessor_type(
1000 pSrcBmp
->maAccessor
,
1001 pMask
->maRawAccessor
),
1003 destIterRange(begin
,
1004 typename masked_input_splitting_accessor
<
1006 joined_image_accessor_type
,
1007 Masks::clipmask_polarity
,
1008 FastMask
>::type(acc
),
1010 isSharedBuffer(rSrcBitmap
));
1011 damaged( rDstRect
);
1014 template< typename Iterator
, typename Acc
>
1015 void implDrawMaskedBitmapGeneric(const BitmapDeviceSharedPtr
& rSrcBitmap
,
1016 const BitmapDeviceSharedPtr
& rMask
,
1017 const basegfx::B2IBox
& rSrcRect
,
1018 const basegfx::B2IBox
& rDstRect
,
1019 const Iterator
& begin
,
1022 GenericColorImageAccessor
aSrcAcc( rSrcBitmap
);
1023 GenericColorImageAccessor
aMaskAcc( rMask
);
1025 const vigra::Diff2D
aTopLeft(rSrcRect
.getMinX(),
1026 rSrcRect
.getMinY());
1027 const vigra::Diff2D
aBottomRight(rSrcRect
.getMaxX(),
1028 rSrcRect
.getMaxY());
1031 generic_composite_iterator_type(
1033 generic_composite_iterator_type(
1034 aBottomRight
,aBottomRight
),
1035 joined_generic_image_accessor_type(
1038 destIterRange(begin
,
1039 typename masked_input_splitting_accessor
<
1041 joined_generic_image_accessor_type
,
1042 Masks::clipmask_polarity
,
1043 NoFastMask
>::type(acc
),
1045 damaged( rDstRect
);
1048 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
1049 const BitmapDeviceSharedPtr
& rMask
,
1050 const basegfx::B2IBox
& rSrcRect
,
1051 const basegfx::B2IBox
& rDstRect
,
1052 DrawMode drawMode
) SAL_OVERRIDE
1054 if( isCompatibleClipMask(rMask
) &&
1055 isCompatibleBitmap(rSrcBitmap
) )
1057 if( drawMode
== DrawMode_XOR
)
1058 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1063 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1070 if( drawMode
== DrawMode_XOR
)
1071 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1076 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1081 damaged( rDstRect
);
1084 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr
& rSrcBitmap
,
1085 const BitmapDeviceSharedPtr
& rMask
,
1086 const basegfx::B2IBox
& rSrcRect
,
1087 const basegfx::B2IBox
& rDstRect
,
1089 const BitmapDeviceSharedPtr
& rClip
) SAL_OVERRIDE
1091 if( isCompatibleClipMask(rMask
) &&
1092 isCompatibleBitmap(rSrcBitmap
) )
1094 if( drawMode
== DrawMode_XOR
)
1095 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1097 getMaskedIter(rClip
),
1098 maMaskedXorAccessor
);
1100 implDrawMaskedBitmap(rSrcBitmap
, rMask
,
1102 getMaskedIter(rClip
),
1107 if( drawMode
== DrawMode_XOR
)
1108 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1110 getMaskedIter(rClip
),
1111 maMaskedXorAccessor
);
1113 implDrawMaskedBitmapGeneric(rSrcBitmap
, rMask
,
1115 getMaskedIter(rClip
),
1118 damaged( rDstRect
);
1121 IBitmapDeviceDamageTrackerSharedPtr
getDamageTracker_i() const SAL_OVERRIDE
1125 void setDamageTracker_i( const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
) SAL_OVERRIDE
1132 struct ImplBitmapDevice
1134 /** Bitmap memory plus deleter.
1136 Always points to the start of the mem
1138 RawMemorySharedArray mpMem
;
1140 /// Palette memory plus deleter (might be NULL)
1141 PaletteMemorySharedVector mpPalette
;
1143 /** Bounds of the device.
1145 maBounds.getWidth()/getHeight() yield the true size of the
1146 device (i.e. the rectangle given by maBounds covers the device
1147 area under the including-the-bottommost-and-rightmost-pixels
1150 basegfx::B2IBox maBounds
;
1152 //// Size of the actual frame buffer
1153 basegfx::B2IVector maBufferSize
;
1155 /// Scanline format, as provided at the constructor
1156 Format mnScanlineFormat
;
1158 /// Scanline stride. Negative for bottom-to-top formats
1159 sal_Int32 mnScanlineStride
;
1161 /// raw ptr to 0th scanline. used for cloning a generic renderer
1162 sal_uInt8
* mpFirstScanline
;
1164 /** (Optional) device sharing the same memory, and used for input
1165 clip masks/alpha masks/bitmaps that don't match our exact
1168 This is to avoid the combinatorical explosion when dealing
1169 with n bitmap formats, which could be combined with n clip
1170 masks, alpha masks and bitmap masks (yielding a total of n^4
1171 combinations). Since each BitmapRenderer is specialized for
1172 one specific combination of said formats, a lot of duplicate
1173 code would be generated, most of which probably never
1174 used. Therefore, only the most common combinations are
1175 specialized templates, the remainder gets handled by this
1176 generic renderer (via runtime polymorphism).
1178 BitmapDeviceSharedPtr mpGenericRenderer
;
1182 BitmapDevice::BitmapDevice( const basegfx::B2IBox
& rBounds
,
1183 const basegfx::B2IVector
& rBufferSize
,
1184 Format nScanlineFormat
,
1185 sal_Int32 nScanlineStride
,
1186 sal_uInt8
* pFirstScanline
,
1187 const RawMemorySharedArray
& rMem
,
1188 const PaletteMemorySharedVector
& rPalette
) :
1189 mpImpl( new ImplBitmapDevice
)
1191 mpImpl
->mpMem
= rMem
;
1192 mpImpl
->mpPalette
= rPalette
;
1193 mpImpl
->maBounds
= rBounds
;
1194 mpImpl
->maBufferSize
= rBufferSize
;
1195 mpImpl
->mnScanlineFormat
= nScanlineFormat
;
1196 mpImpl
->mnScanlineStride
= nScanlineStride
;
1197 mpImpl
->mpFirstScanline
= pFirstScanline
;
1200 BitmapDevice::~BitmapDevice()
1202 // outline, because of internal ImplBitmapDevice
1203 SAL_INFO( "basebmp.bitmapdevice", "~BitmapDevice(" << this << ")" );
1206 basegfx::B2IVector
BitmapDevice::getSize() const
1208 return basegfx::B2IVector(
1209 mpImpl
->maBounds
.getMaxX() - mpImpl
->maBounds
.getMinX(),
1210 mpImpl
->maBounds
.getMaxY() - mpImpl
->maBounds
.getMinY() );
1213 bool BitmapDevice::isTopDown() const
1215 return mpImpl
->mnScanlineStride
>= 0;
1218 basegfx::B2IVector
BitmapDevice::getBufferSize() const
1220 return mpImpl
->maBufferSize
;
1223 Format
BitmapDevice::getScanlineFormat() const
1225 return mpImpl
->mnScanlineFormat
;
1228 sal_Int32
BitmapDevice::getScanlineStride() const
1230 return mpImpl
->mnScanlineStride
< 0 ?
1231 -mpImpl
->mnScanlineStride
: mpImpl
->mnScanlineStride
;
1234 RawMemorySharedArray
BitmapDevice::getBuffer() const
1236 return mpImpl
->mpMem
;
1239 IBitmapDeviceDamageTrackerSharedPtr
BitmapDevice::getDamageTracker() const
1241 return getDamageTracker_i();
1244 void BitmapDevice::setDamageTracker( const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
)
1246 setDamageTracker_i(rDamage
);
1249 PaletteMemorySharedVector
BitmapDevice::getPalette() const
1251 return mpImpl
->mpPalette
;
1254 bool BitmapDevice::isSharedBuffer( const BitmapDeviceSharedPtr
& rOther
) const
1256 return rOther
.get()->getBuffer().get() == getBuffer().get();
1259 void BitmapDevice::clear( Color fillColor
)
1261 clear_i( fillColor
, mpImpl
->maBounds
);
1264 void BitmapDevice::setPixel( const basegfx::B2IPoint
& rPt
,
1268 if( mpImpl
->maBounds
.isInside(rPt
) )
1269 setPixel_i(rPt
,lineColor
,drawMode
);
1272 void BitmapDevice::setPixel( const basegfx::B2IPoint
& rPt
,
1275 const BitmapDeviceSharedPtr
& rClip
)
1279 setPixel(rPt
,lineColor
,drawMode
);
1283 if( mpImpl
->maBounds
.isInside(rPt
) )
1285 if( isCompatibleClipMask( rClip
) )
1286 setPixel_i(rPt
,lineColor
,drawMode
,rClip
);
1288 getGenericRenderer()->setPixel( rPt
, lineColor
, drawMode
, rClip
);
1292 Color
BitmapDevice::getPixel( const basegfx::B2IPoint
& rPt
)
1294 if( mpImpl
->maBounds
.isInside(rPt
) )
1295 return getPixel_i(rPt
);
1300 sal_uInt32
BitmapDevice::getPixelData( const basegfx::B2IPoint
& rPt
)
1302 if( mpImpl
->maBounds
.isInside(rPt
) )
1303 return getPixelData_i(rPt
);
1308 void BitmapDevice::drawLine( const basegfx::B2IPoint
& rPt1
,
1309 const basegfx::B2IPoint
& rPt2
,
1320 void BitmapDevice::drawLine( const basegfx::B2IPoint
& rPt1
,
1321 const basegfx::B2IPoint
& rPt2
,
1324 const BitmapDeviceSharedPtr
& rClip
)
1328 drawLine(rPt1
,rPt2
,lineColor
,drawMode
);
1332 if( isCompatibleClipMask( rClip
) )
1340 getGenericRenderer()->drawLine( rPt1
, rPt2
, lineColor
,
1344 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon
& rPoly
,
1348 const sal_uInt32
numVertices( rPoly
.count() );
1350 drawPolygon_i( rPoly
,
1352 lineColor
, drawMode
);
1355 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon
& rPoly
,
1358 const BitmapDeviceSharedPtr
& rClip
)
1362 drawPolygon(rPoly
,lineColor
,drawMode
);
1366 const sal_uInt32
numVertices( rPoly
.count() );
1369 if( isCompatibleClipMask( rClip
) )
1370 drawPolygon_i( rPoly
,
1372 lineColor
, drawMode
, rClip
);
1374 getGenericRenderer()->drawPolygon( rPoly
, lineColor
,
1379 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon
& rPoly
,
1383 fillPolyPolygon_i( rPoly
, fillColor
, drawMode
, mpImpl
->maBounds
);
1386 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon
& rPoly
,
1389 const BitmapDeviceSharedPtr
& rClip
)
1393 fillPolyPolygon(rPoly
,fillColor
,drawMode
);
1397 if( isCompatibleClipMask( rClip
) )
1398 fillPolyPolygon_i( rPoly
, fillColor
, drawMode
, mpImpl
->maBounds
, rClip
);
1400 getGenericRenderer()->fillPolyPolygon( rPoly
, fillColor
,
1407 void assertImagePoint( const basegfx::B2IPoint
& rPt
,
1408 const basegfx::B2IBox
& rPermittedRange
)
1410 (void)rPt
; (void)rPermittedRange
;
1411 OSL_ASSERT( rPermittedRange
.isInside(rPt
) );
1414 void assertImageRange( const basegfx::B2IBox
& rRange
,
1415 const basegfx::B2IBox
& rPermittedRange
)
1417 #if OSL_DEBUG_LEVEL > 0
1418 basegfx::B2IBox
aRange( rRange
);
1419 aRange
.intersect( rPermittedRange
);
1421 OSL_ASSERT( aRange
== rRange
);
1423 (void)rRange
; (void)rPermittedRange
;
1427 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1428 // to basegfx, and use here!
1429 bool clipAreaImpl( ::basegfx::B2IBox
& io_rSourceArea
,
1430 ::basegfx::B2IPoint
& io_rDestPoint
,
1431 const ::basegfx::B2IBox
& rSourceBounds
,
1432 const ::basegfx::B2IBox
& rDestBounds
)
1434 const ::basegfx::B2IPoint
aSourceTopLeft(
1435 io_rSourceArea
.getMinimum() );
1437 ::basegfx::B2IBox
aLocalSourceArea( io_rSourceArea
);
1439 // clip source area (which must be inside rSourceBounds)
1440 aLocalSourceArea
.intersect( rSourceBounds
);
1442 if( aLocalSourceArea
.isEmpty() )
1445 // calc relative new source area points (relative to orig
1447 const ::basegfx::B2IVector
aUpperLeftOffset(
1448 aLocalSourceArea
.getMinimum()-aSourceTopLeft
);
1449 const ::basegfx::B2IVector
aLowerRightOffset(
1450 aLocalSourceArea
.getMaximum()-aSourceTopLeft
);
1452 ::basegfx::B2IBox
aLocalDestArea( io_rDestPoint
+ aUpperLeftOffset
,
1453 io_rDestPoint
+ aLowerRightOffset
);
1455 // clip dest area (which must be inside rDestBounds)
1456 aLocalDestArea
.intersect( rDestBounds
);
1458 if( aLocalDestArea
.isEmpty() )
1461 // calc relative new dest area points (relative to orig
1463 const ::basegfx::B2IVector
aDestUpperLeftOffset(
1464 aLocalDestArea
.getMinimum()-io_rDestPoint
);
1465 const ::basegfx::B2IVector
aDestLowerRightOffset(
1466 aLocalDestArea
.getMaximum()-io_rDestPoint
);
1468 io_rSourceArea
= ::basegfx::B2IBox( aSourceTopLeft
+ aDestUpperLeftOffset
,
1469 aSourceTopLeft
+ aDestLowerRightOffset
);
1470 io_rDestPoint
= aLocalDestArea
.getMinimum();
1475 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1476 // to basegfx, and use here!
1477 bool clipAreaImpl( ::basegfx::B2IBox
& io_rDestArea
,
1478 ::basegfx::B2IBox
& io_rSourceArea
,
1479 const ::basegfx::B2IBox
& rDestBounds
,
1480 const ::basegfx::B2IBox
& rSourceBounds
)
1482 // extract inherent scale
1483 double fWidth
= io_rSourceArea
.getWidth();
1487 double fHeight
= io_rSourceArea
.getHeight();
1491 const double nScaleX( io_rDestArea
.getWidth() / fWidth
);
1492 const double nScaleY( io_rDestArea
.getHeight() / fHeight
);
1494 // extract range origins
1495 const basegfx::B2IPoint
aDestTopLeft(
1496 io_rDestArea
.getMinimum() );
1497 const ::basegfx::B2IPoint
aSourceTopLeft(
1498 io_rSourceArea
.getMinimum() );
1500 ::basegfx::B2IBox
aLocalSourceArea( io_rSourceArea
);
1502 // clip source area (which must be inside rSourceBounds)
1503 aLocalSourceArea
.intersect( rSourceBounds
);
1505 if( aLocalSourceArea
.isEmpty() )
1508 // calc relative new source area points (relative to orig
1510 const ::basegfx::B2IVector
aUpperLeftOffset(
1511 aLocalSourceArea
.getMinimum()-aSourceTopLeft
);
1512 const ::basegfx::B2IVector
aLowerRightOffset(
1513 aLocalSourceArea
.getMaximum()-aSourceTopLeft
);
1515 ::basegfx::B2IBox
aLocalDestArea( basegfx::fround(aDestTopLeft
.getX() + nScaleX
*aUpperLeftOffset
.getX()),
1516 basegfx::fround(aDestTopLeft
.getY() + nScaleY
*aUpperLeftOffset
.getY()),
1517 basegfx::fround(aDestTopLeft
.getX() + nScaleX
*aLowerRightOffset
.getX()),
1518 basegfx::fround(aDestTopLeft
.getY() + nScaleY
*aLowerRightOffset
.getY()) );
1520 // clip dest area (which must be inside rDestBounds)
1521 aLocalDestArea
.intersect( rDestBounds
);
1523 if( aLocalDestArea
.isEmpty() )
1526 // calc relative new dest area points (relative to orig
1528 const ::basegfx::B2IVector
aDestUpperLeftOffset(
1529 aLocalDestArea
.getMinimum()-aDestTopLeft
);
1530 const ::basegfx::B2IVector
aDestLowerRightOffset(
1531 aLocalDestArea
.getMaximum()-aDestTopLeft
);
1533 io_rSourceArea
= ::basegfx::B2IBox( basegfx::fround(aSourceTopLeft
.getX() + aDestUpperLeftOffset
.getX()/nScaleX
),
1534 basegfx::fround(aSourceTopLeft
.getY() + aDestUpperLeftOffset
.getY()/nScaleY
),
1535 basegfx::fround(aSourceTopLeft
.getX() + aDestLowerRightOffset
.getX()/nScaleX
),
1536 basegfx::fround(aSourceTopLeft
.getY() + aDestLowerRightOffset
.getY()/nScaleY
) );
1537 io_rDestArea
= aLocalDestArea
;
1539 // final source area clip (chopping round-offs)
1540 io_rSourceArea
.intersect( rSourceBounds
);
1542 if( io_rSourceArea
.isEmpty() )
1550 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1551 const basegfx::B2IBox
& rSrcRect
,
1552 const basegfx::B2IBox
& rDstRect
,
1555 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1556 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1557 basegfx::B2IBox
aSrcRange( rSrcRect
);
1558 basegfx::B2IBox
aDestRange( rDstRect
);
1560 if( clipAreaImpl( aDestRange
,
1565 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1566 assertImageRange(aSrcRange
,aSrcBounds
);
1568 drawBitmap_i( rSrcBitmap
, aSrcRange
, aDestRange
, drawMode
);
1572 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1573 const basegfx::B2IBox
& rSrcRect
,
1574 const basegfx::B2IBox
& rDstRect
,
1576 const BitmapDeviceSharedPtr
& rClip
)
1580 drawBitmap(rSrcBitmap
,rSrcRect
,rDstRect
,drawMode
);
1584 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1585 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1586 basegfx::B2IBox
aSrcRange( rSrcRect
);
1587 basegfx::B2IBox
aDestRange( rDstRect
);
1589 if( clipAreaImpl( aDestRange
,
1594 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1595 assertImageRange(aSrcRange
,aSrcBounds
);
1597 if( isCompatibleClipMask( rClip
) )
1599 drawBitmap_i( rSrcBitmap
, aSrcRange
, aDestRange
, drawMode
, rClip
);
1603 getGenericRenderer()->drawBitmap( rSrcBitmap
, rSrcRect
,
1604 rDstRect
, drawMode
, rClip
);
1609 void BitmapDevice::drawMaskedColor( Color aSrcColor
,
1610 const BitmapDeviceSharedPtr
& rAlphaMask
,
1611 const basegfx::B2IBox
& rSrcRect
,
1612 const basegfx::B2IPoint
& rDstPoint
)
1614 const basegfx::B2IVector
& rSrcSize( rAlphaMask
->getSize() );
1615 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1616 basegfx::B2IBox
aSrcRange( rSrcRect
);
1617 basegfx::B2IPoint
aDestPoint( rDstPoint
);
1619 if( clipAreaImpl( aSrcRange
,
1624 assertImagePoint(aDestPoint
,mpImpl
->maBounds
);
1625 assertImageRange(aSrcRange
,aSrcBounds
);
1627 if( isSharedBuffer(rAlphaMask
) )
1629 // src == dest, copy rAlphaMask beforehand
1632 const basegfx::B2ITuple
aSize( aSrcRange
.getWidth(),
1633 aSrcRange
.getHeight() );
1634 BitmapDeviceSharedPtr
pAlphaCopy(
1635 cloneBitmapDevice( aSize
,
1636 shared_from_this()) );
1637 const basegfx::B2IBox
aAlphaRange( basegfx::B2ITuple(),
1639 pAlphaCopy
->drawBitmap(rAlphaMask
,
1643 drawMaskedColor_i( aSrcColor
, pAlphaCopy
, aAlphaRange
, aDestPoint
);
1647 drawMaskedColor_i( aSrcColor
, rAlphaMask
, aSrcRange
, aDestPoint
);
1652 void BitmapDevice::drawMaskedColor( Color aSrcColor
,
1653 const BitmapDeviceSharedPtr
& rAlphaMask
,
1654 const basegfx::B2IBox
& rSrcRect
,
1655 const basegfx::B2IPoint
& rDstPoint
,
1656 const BitmapDeviceSharedPtr
& rClip
)
1660 drawMaskedColor(aSrcColor
,rAlphaMask
,rSrcRect
,rDstPoint
);
1664 const basegfx::B2IVector
& rSrcSize( rAlphaMask
->getSize() );
1665 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1666 basegfx::B2IBox
aSrcRange( rSrcRect
);
1667 basegfx::B2IPoint
aDestPoint( rDstPoint
);
1669 if( clipAreaImpl( aSrcRange
,
1674 assertImagePoint(aDestPoint
,mpImpl
->maBounds
);
1675 assertImageRange(aSrcRange
,aSrcBounds
);
1677 if( isCompatibleClipMask( rClip
) )
1679 if( isSharedBuffer(rAlphaMask
) )
1681 // src == dest, copy rAlphaMask beforehand
1684 const basegfx::B2ITuple
aSize( aSrcRange
.getWidth(),
1685 aSrcRange
.getHeight() );
1686 BitmapDeviceSharedPtr
pAlphaCopy(
1687 cloneBitmapDevice( aSize
,
1688 shared_from_this()) );
1689 const basegfx::B2IBox
aAlphaRange( basegfx::B2ITuple(),
1691 pAlphaCopy
->drawBitmap(rAlphaMask
,
1695 drawMaskedColor_i( aSrcColor
, pAlphaCopy
, aAlphaRange
, aDestPoint
, rClip
);
1699 drawMaskedColor_i( aSrcColor
, rAlphaMask
, aSrcRange
, aDestPoint
, rClip
);
1704 getGenericRenderer()->drawMaskedColor( aSrcColor
, rAlphaMask
,
1705 rSrcRect
, rDstPoint
, rClip
);
1710 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1711 const BitmapDeviceSharedPtr
& rMask
,
1712 const basegfx::B2IBox
& rSrcRect
,
1713 const basegfx::B2IBox
& rDstRect
,
1716 OSL_ASSERT( rMask
->getSize() == rSrcBitmap
->getSize() );
1718 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1719 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1720 basegfx::B2IBox
aSrcRange( rSrcRect
);
1721 basegfx::B2IBox
aDestRange( rDstRect
);
1723 if( clipAreaImpl( aDestRange
,
1728 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1729 assertImageRange(aSrcRange
,aSrcBounds
);
1731 drawMaskedBitmap_i( rSrcBitmap
, rMask
, aSrcRange
, aDestRange
, drawMode
);
1735 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr
& rSrcBitmap
,
1736 const BitmapDeviceSharedPtr
& rMask
,
1737 const basegfx::B2IBox
& rSrcRect
,
1738 const basegfx::B2IBox
& rDstRect
,
1740 const BitmapDeviceSharedPtr
& rClip
)
1744 drawMaskedBitmap(rSrcBitmap
,rMask
,rSrcRect
,rDstRect
,drawMode
);
1748 OSL_ASSERT( rMask
->getSize() == rSrcBitmap
->getSize() );
1750 const basegfx::B2IVector
& rSrcSize( rSrcBitmap
->getSize() );
1751 const basegfx::B2IBox
aSrcBounds( 0,0,rSrcSize
.getX(),rSrcSize
.getY() );
1752 basegfx::B2IBox
aSrcRange( rSrcRect
);
1753 basegfx::B2IBox
aDestRange( rDstRect
);
1755 if( clipAreaImpl( aDestRange
,
1760 assertImageRange(aDestRange
,mpImpl
->maBounds
);
1761 assertImageRange(aSrcRange
,aSrcBounds
);
1763 if( isCompatibleClipMask( rClip
) )
1765 drawMaskedBitmap_i( rSrcBitmap
, rMask
, aSrcRange
, aDestRange
, drawMode
, rClip
);
1769 getGenericRenderer()->drawMaskedBitmap( rSrcBitmap
, rMask
, rSrcRect
,
1770 rDstRect
, drawMode
, rClip
);
1777 /** Standard clip and alpha masks
1781 typedef PixelFormatTraits_GREY1_MSB clipmask_format_traits
;
1782 typedef PixelFormatTraits_GREY8 alphamask_format_traits
;
1784 /// Clipmask: 0 means opaque
1785 static const bool clipmask_polarity
= false;
1787 /// Alpha mask: 0 means fully transparent
1788 static const bool alphamask_polarity
= true;
1792 // Some compilers don't like the nested template wrap_accessor
1793 // reference in the parameter list - being slightly less type safe,
1795 #ifndef BASEBMP_NO_NESTED_TEMPLATE_PARAMETER
1797 /// Produces a specialized renderer for the given pixel format
1798 template< class FormatTraits
, class MaskTraits
>
1799 BitmapDeviceSharedPtr
createRenderer(
1800 const basegfx::B2IBox
& rBounds
,
1801 const basegfx::B2IVector
& rBufferSize
,
1802 Format nScanlineFormat
,
1803 sal_Int32 nScanlineStride
,
1804 sal_uInt8
* pFirstScanline
,
1805 typename
FormatTraits::raw_accessor_type
const& rRawAccessor
,
1806 typename
FormatTraits::accessor_selector::template wrap_accessor
<
1807 typename
FormatTraits::raw_accessor_type
>::type
const& rAccessor
,
1808 boost::shared_array
< sal_uInt8
> pMem
,
1809 const PaletteMemorySharedVector
& pPal
,
1810 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1813 template< class FormatTraits
, class MaskTraits
, class Accessor
>
1814 BitmapDeviceSharedPtr
createRenderer(
1815 const basegfx::B2IBox
& rBounds
,
1816 const basegfx::B2IVector
& rBufferSize
,
1817 Format nScanlineFormat
,
1818 sal_Int32 nScanlineStride
,
1819 sal_uInt8
* pFirstScanline
,
1820 typename
FormatTraits::raw_accessor_type
const& rRawAccessor
,
1821 Accessor
const& rAccessor
,
1822 boost::shared_array
< sal_uInt8
> pMem
,
1823 const PaletteMemorySharedVector
& pPal
,
1824 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1828 typedef typename
FormatTraits::iterator_type Iterator
;
1829 typedef BitmapRenderer
< Iterator
,
1830 typename
FormatTraits::raw_accessor_type
,
1831 typename
FormatTraits::accessor_selector
,
1832 MaskTraits
> Renderer
;
1834 return BitmapDeviceSharedPtr(
1835 new Renderer( rBounds
,
1841 reinterpret_cast<typename
Iterator::value_type
*>(
1851 /// Create standard grey level palette
1852 PaletteMemorySharedVector
createStandardPalette(
1853 const PaletteMemorySharedVector
& pPal
,
1854 sal_Int32 nNumEntries
)
1856 if( pPal
|| nNumEntries
<= 0 )
1859 boost::shared_ptr
< std::vector
<Color
> > pLocalPal(
1860 new std::vector
<Color
>(nNumEntries
) );
1862 const sal_Int32
nIncrement( 0x00FFFFFF/nNumEntries
);
1864 for( sal_Int32 i
=0, c
=0; i
<nNumEntries
; ++i
,c
+=nIncrement
)
1865 pLocalPal
->at(i
) = Color(0xFF000000 | c
);
1867 pLocalPal
->at(nNumEntries
) = Color(0xFFFFFFFF);
1872 template< class FormatTraits
, class MaskTraits
>
1873 BitmapDeviceSharedPtr
createRenderer(
1874 const basegfx::B2IBox
& rBounds
,
1875 const basegfx::B2IVector
& rBufferSize
,
1876 Format nScanlineFormat
,
1877 sal_Int32 nScanlineStride
,
1878 sal_uInt8
* pFirstScanline
,
1879 boost::shared_array
< sal_uInt8
> pMem
,
1880 const PaletteMemorySharedVector
& pPal
,
1881 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1883 return createRenderer
<FormatTraits
,
1884 MaskTraits
>(rBounds
,
1889 typename
FormatTraits::raw_accessor_type(),
1890 typename
FormatTraits::accessor_selector::template
1892 typename
FormatTraits::raw_accessor_type
>::type(),
1898 template< class FormatTraits
, class MaskTraits
>
1899 BitmapDeviceSharedPtr
createRenderer(
1900 const basegfx::B2IBox
& rBounds
,
1901 const basegfx::B2IVector
& rBufferSize
,
1902 Format nScanlineFormat
,
1903 sal_Int32 nScanlineStride
,
1904 sal_uInt8
* pFirstScanline
,
1905 boost::shared_array
< sal_uInt8
> pMem
,
1906 PaletteMemorySharedVector pPal
,
1908 const IBitmapDeviceDamageTrackerSharedPtr
& pDamage
)
1910 pPal
= createStandardPalette(pPal
,
1911 1UL << nBitsPerPixel
);
1914 return createRenderer
<FormatTraits
,
1915 MaskTraits
>(rBounds
,
1920 typename
FormatTraits::raw_accessor_type(),
1921 typename
FormatTraits::accessor_selector::template
1923 typename
FormatTraits::raw_accessor_type
>::type(
1932 // TODO(Q3): consolidate with canvas/canvastools.hxx! Best move this
1933 // to o3tl or sal/bithacks.hxx ...
1935 /** Compute the next highest power of 2 of a 32-bit value
1937 Code devised by Sean Anderson, in good ole HAKMEM
1940 @return 1 << (lg(x - 1) + 1)
1942 inline sal_uInt32
nextPow2( sal_uInt32 x
)
1956 BitmapDeviceSharedPtr
createBitmapDeviceImplInner( const basegfx::B2IVector
& rSize
,
1958 Format nScanlineFormat
,
1959 sal_Int32 nScanlineStride
,
1960 boost::shared_array
< sal_uInt8
> pMem
,
1961 PaletteMemorySharedVector pPal
,
1962 const basegfx::B2IBox
* pSubset
,
1963 const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
,
1966 OSL_ASSERT(rSize
.getX() > 0 && rSize
.getY() > 0);
1968 if( nScanlineFormat
<= FORMAT_NONE
||
1969 nScanlineFormat
> FORMAT_MAX
)
1970 return BitmapDeviceSharedPtr();
1972 sal_uInt8 nBitsPerPixel
= bitsPerPixel
[nScanlineFormat
];
1973 if (rSize
.getX() > (SAL_MAX_INT32
-7) / nBitsPerPixel
)
1975 SAL_WARN("basebmp", "suspicious bitmap width " <<
1976 rSize
.getX() << " for depth " << nBitsPerPixel
);
1977 return BitmapDeviceSharedPtr();
1980 // factor in bottom-up scanline order case
1981 nScanlineStride
*= bTopDown
? 1 : -1;
1983 const sal_uInt32
nWidth(nScanlineStride
< 0 ? -nScanlineStride
: nScanlineStride
);
1984 const sal_uInt32
nHeight(rSize
.getY());
1986 if (nHeight
&& nWidth
&& nWidth
> SAL_MAX_INT32
/ nHeight
)
1988 SAL_WARN( "basebmp", "suspicious massive alloc " << nWidth
<< " * " << nHeight
);
1989 return BitmapDeviceSharedPtr();
1992 const std::size_t nMemSize(nWidth
* nHeight
);
1997 static_cast<sal_uInt8
*>(rtl_allocateMemory( nMemSize
)),
1999 if (pMem
.get() == 0 && nMemSize
!= 0)
2000 return BitmapDeviceSharedPtr();
2002 memset(pMem
.get(), 0, nMemSize
);
2004 memset(pMem
.get(), 0xFF, nMemSize
);
2007 sal_uInt8
* pFirstScanline
= nScanlineStride
< 0 ?
2008 pMem
.get() + nMemSize
+ nScanlineStride
: pMem
.get();
2010 // shrink render area to given subset, if given
2011 basegfx::B2IBox
aBounds(0,0,rSize
.getX(),rSize
.getY());
2013 aBounds
.intersect( *pSubset
);
2015 switch( nScanlineFormat
)
2020 case FORMAT_ONE_BIT_MSB_GREY
:
2021 return createRenderer
<PixelFormatTraits_GREY1_MSB
,StdMasks
>(
2022 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2023 pFirstScanline
, pMem
, pPal
, rDamage
);
2025 case FORMAT_ONE_BIT_LSB_GREY
:
2026 return createRenderer
<PixelFormatTraits_GREY1_LSB
,StdMasks
>(
2027 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2028 pFirstScanline
, pMem
, pPal
, rDamage
);
2030 case FORMAT_ONE_BIT_MSB_PAL
:
2031 return createRenderer
<PixelFormatTraits_PAL1_MSB
,StdMasks
>(
2032 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2033 pFirstScanline
, pMem
, pPal
,
2034 bitsPerPixel
[nScanlineFormat
], rDamage
);
2036 case FORMAT_ONE_BIT_LSB_PAL
:
2037 return createRenderer
<PixelFormatTraits_PAL1_LSB
,StdMasks
>(
2038 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2039 pFirstScanline
, pMem
, pPal
,
2040 bitsPerPixel
[nScanlineFormat
], rDamage
);
2046 case FORMAT_FOUR_BIT_MSB_GREY
:
2047 return createRenderer
<PixelFormatTraits_GREY4_MSB
,StdMasks
>(
2048 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2049 pFirstScanline
, pMem
, pPal
, rDamage
);
2051 case FORMAT_FOUR_BIT_LSB_GREY
:
2052 return createRenderer
<PixelFormatTraits_GREY4_LSB
,StdMasks
>(
2053 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2054 pFirstScanline
, pMem
, pPal
, rDamage
);
2056 case FORMAT_FOUR_BIT_MSB_PAL
:
2057 return createRenderer
<PixelFormatTraits_PAL4_MSB
,StdMasks
>(
2058 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2059 pFirstScanline
, pMem
, pPal
,
2060 bitsPerPixel
[nScanlineFormat
], rDamage
);
2062 case FORMAT_FOUR_BIT_LSB_PAL
:
2063 return createRenderer
<PixelFormatTraits_PAL4_LSB
,StdMasks
>(
2064 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2065 pFirstScanline
, pMem
, pPal
,
2066 bitsPerPixel
[nScanlineFormat
], rDamage
);
2070 // eight bit formats
2072 case FORMAT_EIGHT_BIT_GREY
:
2073 return createRenderer
<PixelFormatTraits_GREY8
,StdMasks
>(
2074 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2075 pFirstScanline
, pMem
, pPal
, rDamage
);
2077 case FORMAT_EIGHT_BIT_PAL
:
2078 return createRenderer
<PixelFormatTraits_PAL8
,StdMasks
>(
2079 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2080 pFirstScanline
, pMem
, pPal
,
2081 bitsPerPixel
[nScanlineFormat
], rDamage
);
2085 // sixteen bit formats
2087 case FORMAT_SIXTEEN_BIT_LSB_TC_MASK
:
2088 return createRenderer
<PixelFormatTraits_RGB16_565_LSB
,StdMasks
>(
2089 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2090 pFirstScanline
, pMem
, pPal
, rDamage
);
2092 case FORMAT_SIXTEEN_BIT_MSB_TC_MASK
:
2093 return createRenderer
<PixelFormatTraits_RGB16_565_MSB
,StdMasks
>(
2094 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2095 pFirstScanline
, pMem
, pPal
, rDamage
);
2097 // twentyfour bit formats
2098 case FORMAT_TWENTYFOUR_BIT_TC_MASK
:
2099 return createRenderer
<PixelFormatTraits_BGR24
,StdMasks
>(
2100 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2101 pFirstScanline
, pMem
, pPal
, rDamage
);
2103 // thirtytwo bit formats
2105 // 8 red bits, 8 green bits, 8 blue bits, and 8 ignored bits like CAIRO_FORMAT_RGB24
2106 case FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX
:
2107 return createRenderer
<PixelFormatTraits_BGRX32_8888
,StdMasks
>(
2108 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2109 pFirstScanline
, pMem
, pPal
, rDamage
);
2111 case FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA
:
2112 return createRenderer
<PixelFormatTraits_BGRA32_8888
,StdMasks
>(
2113 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2114 pFirstScanline
, pMem
, pPal
, rDamage
);
2116 case FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB
:
2117 return createRenderer
<PixelFormatTraits_ARGB32_8888
,StdMasks
>(
2118 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2119 pFirstScanline
, pMem
, pPal
, rDamage
);
2121 case FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR
:
2122 return createRenderer
<PixelFormatTraits_ABGR32_8888
,StdMasks
>(
2123 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2124 pFirstScanline
, pMem
, pPal
, rDamage
);
2126 case FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA
:
2127 return createRenderer
<PixelFormatTraits_RGBA32_8888
,StdMasks
>(
2128 aBounds
, rSize
, nScanlineFormat
, nScanlineStride
,
2129 pFirstScanline
, pMem
, pPal
, rDamage
);
2132 assert(false); // this cannot happen
2135 // TODO(F3): other formats not yet implemented
2136 return BitmapDeviceSharedPtr();
2139 BitmapDeviceSharedPtr
createBitmapDeviceImpl( const basegfx::B2IVector
& rSize
,
2141 Format nScanlineFormat
,
2142 sal_Int32 nScanlineStride
,
2143 boost::shared_array
< sal_uInt8
> pMem
,
2144 PaletteMemorySharedVector pPal
,
2145 const basegfx::B2IBox
* pSubset
,
2146 const IBitmapDeviceDamageTrackerSharedPtr
& rDamage
,
2149 BitmapDeviceSharedPtr
result( createBitmapDeviceImplInner( rSize
, bTopDown
, nScanlineFormat
, nScanlineStride
, pMem
, pPal
, pSubset
, rDamage
, bBlack
) );
2152 std::ostringstream subset
;
2155 subset
<< " subset=" << pSubset
->getWidth() << "x" << pSubset
->getHeight() << "@(" << pSubset
->getMinX() << "," << pSubset
->getMinY() << ")";
2157 SAL_INFO( "basebmp.bitmapdevice",
2158 "createBitmapDevice: "
2159 << rSize
.getX() << "x" << rSize
.getY()
2160 << (bTopDown
? " top-down " : " bottom-up ")
2161 << formatName(nScanlineFormat
)
2163 << " = " << result
.get() );
2169 sal_Int32
getBitmapDeviceStrideForWidth(Format nScanlineFormat
, sal_Int32 nWidth
)
2171 sal_uInt8 nBitsPerPixel
= bitsPerPixel
[nScanlineFormat
];
2172 // round up to full 8 bit, divide by 8
2173 sal_Int32 nScanlineStride
= (nWidth
*nBitsPerPixel
+ 7) >> 3;
2175 // rounded up to next full power-of-two number of bytes
2176 const sal_uInt32 bytesPerPixel
= nextPow2(
2177 (bitsPerPixel
[nScanlineFormat
] + 7) >> 3);
2179 // now make nScanlineStride a multiple of bytesPerPixel
2180 nScanlineStride
= (nScanlineStride
+ bytesPerPixel
- 1) / bytesPerPixel
* bytesPerPixel
;
2181 return nScanlineStride
;
2184 BitmapDeviceSharedPtr
createBitmapDevice( const basegfx::B2IVector
& rSize
,
2186 Format nScanlineFormat
,
2187 sal_Int32 nScanlineStride
)
2189 return createBitmapDeviceImpl( rSize
,
2193 boost::shared_array
< sal_uInt8
>(),
2194 PaletteMemorySharedVector(),
2196 IBitmapDeviceDamageTrackerSharedPtr() );
2199 BitmapDeviceSharedPtr
createBitmapDevice( const basegfx::B2IVector
& rSize
,
2201 Format nScanlineFormat
,
2202 sal_Int32 nScanlineStride
,
2203 const PaletteMemorySharedVector
& rPalette
)
2205 return createBitmapDeviceImpl( rSize
,
2209 boost::shared_array
< sal_uInt8
>(),
2212 IBitmapDeviceDamageTrackerSharedPtr() );
2215 BitmapDeviceSharedPtr
createBitmapDevice( const basegfx::B2IVector
& rSize
,
2217 Format nScanlineFormat
,
2218 sal_Int32 nScanlineStride
,
2219 const RawMemorySharedArray
& rMem
,
2220 const PaletteMemorySharedVector
& rPalette
)
2222 return createBitmapDeviceImpl( rSize
,
2229 IBitmapDeviceDamageTrackerSharedPtr() );
2232 BitmapDeviceSharedPtr
createClipDevice( const basegfx::B2IVector
& rSize
)
2234 BitmapDeviceSharedPtr
xClip(
2235 createBitmapDeviceImpl( rSize
,
2236 false, /* bTopDown */
2237 basebmp::FORMAT_ONE_BIT_MSB_GREY
,
2238 getBitmapDeviceStrideForWidth(basebmp::FORMAT_ONE_BIT_MSB_GREY
, rSize
.getX()),
2239 boost::shared_array
< sal_uInt8
>(),
2240 PaletteMemorySharedVector(),
2242 IBitmapDeviceDamageTrackerSharedPtr(),
2243 false /* white */) );
2247 BitmapDeviceSharedPtr
subsetBitmapDevice( const BitmapDeviceSharedPtr
& rProto
,
2248 const basegfx::B2IBox
& rSubset
)
2250 SAL_INFO( "basebmp.bitmapdevice", "subsetBitmapDevice: proto=" << rProto
.get() );
2251 return createBitmapDeviceImpl( rProto
->getSize(),
2252 rProto
->isTopDown(),
2253 rProto
->getScanlineFormat(),
2254 rProto
->getScanlineStride(),
2255 rProto
->getBuffer(),
2256 rProto
->getPalette(),
2258 rProto
->getDamageTracker() );
2261 BitmapDeviceSharedPtr
cloneBitmapDevice( const basegfx::B2IVector
& rSize
,
2262 const BitmapDeviceSharedPtr
& rProto
)
2264 return createBitmapDeviceImpl( rSize
,
2265 rProto
->isTopDown(),
2266 rProto
->getScanlineFormat(),
2267 rProto
->getScanlineStride(),
2268 boost::shared_array
< sal_uInt8
>(),
2269 rProto
->getPalette(),
2271 rProto
->getDamageTracker() );
2275 /// Clone our device, with GenericImageAccessor to handle all formats
2276 BitmapDeviceSharedPtr
BitmapDevice::getGenericRenderer() const
2278 return mpImpl
->mpGenericRenderer
;
2281 } // namespace basebmp
2283 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */