Bump for 3.6-28
[LibreOffice.git] / basebmp / source / bitmapdevice.cxx
blobb3676c603edc184a8c276b446989b8849c816be3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "basebmp/bitmapdevice.hxx"
31 #include "basebmp/compositeiterator.hxx"
32 #include "basebmp/iteratortraits.hxx"
34 #include "basebmp/accessor.hxx"
35 #include "basebmp/accessortraits.hxx"
36 #include "basebmp/accessoradapters.hxx"
37 #include "basebmp/colorblendaccessoradapter.hxx"
39 #include "basebmp/color.hxx"
40 #include "basebmp/colormisc.hxx"
41 #include "basebmp/colortraits.hxx"
43 #include "basebmp/greylevelformats.hxx"
44 #include "basebmp/paletteformats.hxx"
45 #include "basebmp/rgbmaskpixelformats.hxx"
46 #include "basebmp/rgb24pixelformats.hxx"
48 #include "basebmp/scanlineformats.hxx"
49 #include "basebmp/fillimage.hxx"
50 #include "basebmp/scaleimage.hxx"
51 #include "basebmp/clippedlinerenderer.hxx"
52 #include "basebmp/polypolygonrenderer.hxx"
53 #include "basebmp/genericcolorimageaccessor.hxx"
55 #include "basebmp/tools.hxx"
56 #include "intconversion.hxx"
58 #include <rtl/alloc.h>
59 #include <rtl/memory.h>
60 #include <osl/diagnose.h>
62 #include <basegfx/tools/tools.hxx>
63 #include <basegfx/tools/canvastools.hxx>
64 #include <basegfx/range/b2ibox.hxx>
65 #include <basegfx/range/b2irange.hxx>
66 #include <basegfx/range/b2drange.hxx>
67 #include <basegfx/polygon/b2dpolygon.hxx>
68 #include <basegfx/polygon/b2dpolygontools.hxx>
69 #include <basegfx/polygon/b2dpolypolygontools.hxx>
70 #include <basegfx/point/b2ipoint.hxx>
71 #include <basegfx/vector/b2ivector.hxx>
73 #include <vigra/iteratortraits.hxx>
74 #include <vigra/rgbvalue.hxx>
75 #include <vigra/copyimage.hxx>
76 #include <vigra/tuple.hxx>
79 namespace vigra
82 /// componentwise xor of an RGBValue (missing from rgbvalue.hxx)
83 template< class Value, unsigned int RedIndex, unsigned int BlueIndex, unsigned int GreenIndex >
84 inline RGBValue<Value, RedIndex, GreenIndex, BlueIndex>
85 operator^( RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& lhs,
86 RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& rhs )
88 RGBValue<Value, RedIndex, GreenIndex, BlueIndex> res(
89 lhs[0] ^ rhs[0],
90 lhs[1] ^ rhs[1],
91 lhs[2] ^ rhs[2]);
92 return res;
96 namespace basebmp
99 namespace
101 /** Create the type for an accessor that takes the (mask,bitmap)
102 input value generated from a JoinImageAccessorAdapter, and
103 pipe that through a mask functor.
105 @tpl DestAccessor
106 Destination bitmap accessor
108 @tpl JoinedAccessor
109 Input accessor, is expected to generate a std::pair as the
110 value type
112 @tpl MaskFunctorMode
113 Either FastMask or NoFastMask, depending on whether the mask
114 is guaranteed to contain only 0s and 1s.
116 template< class DestAccessor,
117 class JoinedAccessor,
118 bool polarity,
119 typename MaskFunctorMode > struct masked_input_splitting_accessor
121 typedef BinarySetterFunctionAccessorAdapter<
122 DestAccessor,
123 BinaryFunctorSplittingWrapper<
124 typename outputMaskFunctorSelector<
125 typename JoinedAccessor::value_type::first_type,
126 typename JoinedAccessor::value_type::second_type,
127 polarity,
128 MaskFunctorMode >::type > > type;
133 // Actual BitmapDevice implementation (templatized by accessor and iterator)
134 //--------------------------------------------------------------------------
136 /** Implementation of the BitmapDevice interface
138 @tpl DestIterator
139 Iterator to access bitmap memory
141 @tpl RawAccessor
142 Raw accessor, to access pixel values directly
144 @tpl AccessorSelector
145 Accessor adapter selector, which, when applying the nested
146 template metafunction wrap_accessor to one of the raw bitmap
147 accessors, yields a member type named 'type', which is a
148 wrapped accessor that map color values.
150 @tpl Masks
151 Traits template, containing nested traits
152 clipmask_format_traits and alphamask_format_traits, which
153 determine what specialized formats are to be used for clip and
154 alpha masks. With those mask formats, clipping and alpha
155 blending is handled natively.
157 template< class DestIterator,
158 class RawAccessor,
159 class AccessorSelector,
160 class Masks > class BitmapRenderer :
161 public BitmapDevice
163 public:
164 typedef DestIterator dest_iterator_type;
165 typedef RawAccessor raw_accessor_type;
166 typedef AccessorSelector accessor_selector;
168 typedef typename Masks::clipmask_format_traits::iterator_type mask_iterator_type;
169 typedef typename Masks::clipmask_format_traits::raw_accessor_type mask_rawaccessor_type;
170 typedef typename Masks::clipmask_format_traits::accessor_selector mask_accessorselector_type;
172 typedef typename Masks::alphamask_format_traits::iterator_type alphamask_iterator_type;
173 typedef typename Masks::alphamask_format_traits::raw_accessor_type alphamask_rawaccessor_type;
174 typedef typename Masks::alphamask_format_traits::accessor_selector alphamask_accessorselector_type;
176 typedef typename AccessorSelector::template wrap_accessor<
177 raw_accessor_type >::type dest_accessor_type;
179 typedef AccessorTraits< dest_accessor_type > accessor_traits;
180 typedef CompositeIterator2D< dest_iterator_type,
181 mask_iterator_type > composite_iterator_type;
182 typedef CompositeIterator2D< vigra::Diff2D,
183 vigra::Diff2D > generic_composite_iterator_type;
185 typedef BitmapRenderer<mask_iterator_type,
186 mask_rawaccessor_type,
187 mask_accessorselector_type,
188 Masks> mask_bitmap_type;
189 typedef BitmapRenderer<alphamask_iterator_type,
190 alphamask_rawaccessor_type,
191 alphamask_accessorselector_type,
192 Masks> alphamask_bitmap_type;
194 // -------------------------------------------------------
196 typedef AccessorTraits< raw_accessor_type > raw_accessor_traits;
197 typedef typename uInt32Converter<
198 typename raw_accessor_type::value_type>::to to_uint32_functor;
200 // -------------------------------------------------------
202 typedef typename raw_accessor_traits::xor_accessor raw_xor_accessor_type;
203 typedef AccessorTraits<raw_xor_accessor_type> raw_xor_accessor_traits;
204 typedef typename accessor_selector::template wrap_accessor<
205 raw_xor_accessor_type >::type xor_accessor_type;
206 typedef AccessorTraits<xor_accessor_type> xor_accessor_traits;
208 // -------------------------------------------------------
210 typedef typename raw_accessor_traits::template masked_accessor<
211 mask_rawaccessor_type,
212 dest_iterator_type,
213 mask_iterator_type,
214 Masks::clipmask_polarity>::type raw_maskedaccessor_type;
215 typedef typename accessor_selector::template wrap_accessor<
216 raw_maskedaccessor_type >::type masked_accessor_type;
217 typedef typename AccessorTraits<
218 raw_maskedaccessor_type>::xor_accessor raw_maskedxor_accessor_type;
219 typedef typename accessor_selector::template wrap_accessor<
220 raw_maskedxor_accessor_type >::type masked_xoraccessor_type;
222 // -------------------------------------------------------
224 // ((iter,mask),mask) special case (e.g. for clipped
225 // drawMaskedColor())
226 typedef AccessorTraits< raw_maskedaccessor_type > raw_maskedaccessor_traits;
227 typedef typename raw_maskedaccessor_traits::template masked_accessor<
228 mask_rawaccessor_type,
229 composite_iterator_type,
230 mask_iterator_type,
231 Masks::clipmask_polarity>::type raw_maskedmask_accessor_type;
233 typedef CompositeIterator2D<
234 composite_iterator_type,
235 mask_iterator_type> composite_composite_mask_iterator_type;
237 // -------------------------------------------------------
239 typedef ConstantColorBlendSetterAccessorAdapter<
240 dest_accessor_type,
241 typename alphamask_rawaccessor_type::value_type,
242 Masks::alphamask_polarity> colorblend_accessor_type;
243 typedef AccessorTraits<colorblend_accessor_type> colorblend_accessor_traits;
244 typedef typename colorblend_accessor_traits::template masked_accessor<
245 mask_rawaccessor_type,
246 dest_iterator_type,
247 mask_iterator_type,
248 Masks::clipmask_polarity>::type masked_colorblend_accessor_type;
250 // -------------------------------------------------------
252 typedef ConstantColorBlendSetterAccessorAdapter<
253 dest_accessor_type,
254 Color,
255 Masks::alphamask_polarity> colorblend_generic_accessor_type;
256 typedef AccessorTraits<colorblend_generic_accessor_type> colorblend_generic_accessor_traits;
257 typedef typename colorblend_generic_accessor_traits::template masked_accessor<
258 mask_rawaccessor_type,
259 dest_iterator_type,
260 mask_iterator_type,
261 Masks::clipmask_polarity>::type masked_colorblend_generic_accessor_type;
263 // -------------------------------------------------------
265 typedef JoinImageAccessorAdapter< dest_accessor_type,
266 mask_rawaccessor_type > joined_image_accessor_type;
267 typedef JoinImageAccessorAdapter< GenericColorImageAccessor,
268 GenericColorImageAccessor > joined_generic_image_accessor_type;
270 // -------------------------------------------------------
272 dest_iterator_type maBegin;
273 typename accessor_traits::color_lookup maColorLookup;
274 IBitmapDeviceDamageTrackerSharedPtr mpDamage;
275 to_uint32_functor maToUInt32Converter;
276 dest_accessor_type maAccessor;
277 colorblend_accessor_type maColorBlendAccessor;
278 colorblend_generic_accessor_type maGenericColorBlendAccessor;
279 raw_accessor_type maRawAccessor;
280 xor_accessor_type maXorAccessor;
281 raw_xor_accessor_type maRawXorAccessor;
282 masked_accessor_type maMaskedAccessor;
283 masked_colorblend_accessor_type maMaskedColorBlendAccessor;
284 masked_colorblend_generic_accessor_type maGenericMaskedColorBlendAccessor;
285 masked_xoraccessor_type maMaskedXorAccessor;
286 raw_maskedaccessor_type maRawMaskedAccessor;
287 raw_maskedxor_accessor_type maRawMaskedXorAccessor;
288 raw_maskedmask_accessor_type maRawMaskedMaskAccessor;
291 // -------------------------------------------------------
293 BitmapRenderer( const basegfx::B2IBox& rBounds,
294 sal_Int32 nScanlineFormat,
295 sal_Int32 nScanlineStride,
296 sal_uInt8* pFirstScanline,
297 dest_iterator_type begin,
298 raw_accessor_type rawAccessor,
299 dest_accessor_type accessor,
300 const RawMemorySharedArray& rMem,
301 const PaletteMemorySharedVector& rPalette,
302 const IBitmapDeviceDamageTrackerSharedPtr& rDamage ) :
303 BitmapDevice( rBounds, nScanlineFormat,
304 nScanlineStride, pFirstScanline, rMem, rPalette ),
305 maBegin( begin ),
306 maColorLookup(),
307 mpDamage(rDamage),
308 maToUInt32Converter(),
309 maAccessor( accessor ),
310 maColorBlendAccessor( accessor ),
311 maGenericColorBlendAccessor( accessor ),
312 maRawAccessor( rawAccessor ),
313 maXorAccessor( accessor ),
314 maRawXorAccessor( rawAccessor ),
315 maMaskedAccessor( accessor ),
316 maMaskedColorBlendAccessor( maColorBlendAccessor ),
317 maGenericMaskedColorBlendAccessor( maGenericColorBlendAccessor ),
318 maMaskedXorAccessor( accessor ),
319 maRawMaskedAccessor( rawAccessor ),
320 maRawMaskedXorAccessor( rawAccessor ),
321 maRawMaskedMaskAccessor( rawAccessor )
324 private:
326 void damaged( const basegfx::B2IBox& rDamageRect ) const
328 if( mpDamage )
329 mpDamage->damaged( rDamageRect );
332 void damagedPointSize( const basegfx::B2IPoint& rPoint,
333 const basegfx::B2IBox& rSize ) const
335 if( mpDamage ) {
336 basegfx::B2IPoint aLower( rPoint.getX() + rSize.getWidth(),
337 rPoint.getY() + rSize.getHeight() );
338 damaged( basegfx::B2IBox( rPoint, aLower ) );
342 void damagedPixel( const basegfx::B2IPoint& rDamagePoint ) const
344 if( !mpDamage )
345 return;
346 basegfx::B2IPoint aEnd( rDamagePoint.getX() + 1,
347 rDamagePoint.getY() + 1 );
348 damaged( basegfx::B2IBox( rDamagePoint, aEnd ) );
351 boost::shared_ptr<BitmapRenderer> getCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
353 return boost::dynamic_pointer_cast< BitmapRenderer >( bmp );
356 virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
358 // TODO(P1): dynamic_cast usually called twice for
359 // compatible formats
360 return getCompatibleBitmap(bmp).get() != NULL;
363 boost::shared_ptr<mask_bitmap_type> getCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const
365 boost::shared_ptr<mask_bitmap_type> pMask( boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ));
367 if( !pMask )
368 return pMask;
370 if( pMask->getSize() != getSize() )
371 pMask.reset();
373 return pMask;
376 virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const
378 // TODO(P1): dynamic_cast usually called twice for
379 // compatible formats
380 return boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ).get() != NULL;
383 boost::shared_ptr<alphamask_bitmap_type> getCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
385 return boost::dynamic_pointer_cast<alphamask_bitmap_type>( bmp );
388 virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
390 // TODO(P1): dynamic_cast usually called twice for
391 // compatible formats
392 return getCompatibleAlphaMask( bmp ).get() != NULL;
395 virtual void clear_i( Color fillColor,
396 const basegfx::B2IBox& rBounds )
398 fillImage(destIterRange(maBegin,
399 maRawAccessor,
400 rBounds),
401 maColorLookup(
402 maAccessor,
403 fillColor) );
404 damaged( rBounds );
407 virtual void setPixel_i( const basegfx::B2IPoint& rPt,
408 Color pixelColor,
409 DrawMode drawMode )
411 const DestIterator pixel( maBegin +
412 vigra::Diff2D(rPt.getX(),
413 rPt.getY()) );
414 if( drawMode == DrawMode_XOR )
415 maXorAccessor.set( pixelColor,
416 pixel );
417 else
418 maAccessor.set( pixelColor,
419 pixel );
420 damagedPixel(rPt);
423 virtual void setPixel_i( const basegfx::B2IPoint& rPt,
424 Color pixelColor,
425 DrawMode drawMode,
426 const BitmapDeviceSharedPtr& rClip )
428 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
429 OSL_ASSERT( pMask );
431 const vigra::Diff2D offset(rPt.getX(),
432 rPt.getY());
434 const composite_iterator_type aIter(
435 maBegin + offset,
436 pMask->maBegin + offset );
438 if( drawMode == DrawMode_XOR )
439 maMaskedXorAccessor.set( pixelColor,
440 aIter );
441 else
442 maMaskedAccessor.set( pixelColor,
443 aIter );
444 damagedPixel(rPt);
447 virtual Color getPixel_i(const basegfx::B2IPoint& rPt )
449 const DestIterator pixel( maBegin +
450 vigra::Diff2D(rPt.getX(),
451 rPt.getY()) );
452 return maAccessor(pixel);
455 virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt )
457 const DestIterator pixel( maBegin +
458 vigra::Diff2D(rPt.getX(),
459 rPt.getY()) );
460 return maToUInt32Converter(maRawAccessor(pixel));
463 template< typename Iterator, typename Col, typename RawAcc >
464 void implRenderLine2( const basegfx::B2IPoint& rPt1,
465 const basegfx::B2IPoint& rPt2,
466 const basegfx::B2IBox& rBounds,
467 Col col,
468 const Iterator& begin,
469 const RawAcc& rawAcc )
471 renderClippedLine( rPt1,
472 rPt2,
473 rBounds,
474 col,
475 begin,
476 rawAcc );
477 // TODO(P2): perhaps this needs pushing up the stack a bit
478 // to make more complex polygons more efficient ...
479 damaged( basegfx::B2IBox( rPt1, rPt2 ) );
482 template< typename Iterator, typename Accessor, typename RawAcc >
483 void implRenderLine( const basegfx::B2IPoint& rPt1,
484 const basegfx::B2IPoint& rPt2,
485 const basegfx::B2IBox& rBounds,
486 Color col,
487 const Iterator& begin,
488 const Accessor& acc,
489 const RawAcc& rawAcc )
491 implRenderLine2( rPt1,rPt2,rBounds,
492 maColorLookup( acc,
493 col ),
494 begin,
495 rawAcc );
498 template< typename Iterator, typename RawAcc, typename XorAcc >
499 void implDrawLine( const basegfx::B2IPoint& rPt1,
500 const basegfx::B2IPoint& rPt2,
501 const basegfx::B2IBox& rBounds,
502 Color col,
503 const Iterator& begin,
504 const RawAcc& rawAcc,
505 const XorAcc& xorAcc,
506 DrawMode drawMode )
508 if( drawMode == DrawMode_XOR )
509 implRenderLine( rPt1, rPt2, rBounds, col,
510 begin, maAccessor, xorAcc );
511 else
512 implRenderLine( rPt1, rPt2, rBounds, col,
513 begin, maAccessor, rawAcc );
516 virtual void drawLine_i(const basegfx::B2IPoint& rPt1,
517 const basegfx::B2IPoint& rPt2,
518 const basegfx::B2IBox& rBounds,
519 Color lineColor,
520 DrawMode drawMode )
522 implDrawLine(rPt1,rPt2,rBounds,lineColor,
523 maBegin,
524 maRawAccessor,maRawXorAccessor,drawMode);
527 composite_iterator_type getMaskedIter( const BitmapDeviceSharedPtr& rClip ) const
529 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
530 OSL_ASSERT( pMask );
532 return composite_iterator_type( maBegin,
533 pMask->maBegin );
536 virtual void drawLine_i(const basegfx::B2IPoint& rPt1,
537 const basegfx::B2IPoint& rPt2,
538 const basegfx::B2IBox& rBounds,
539 Color lineColor,
540 DrawMode drawMode,
541 const BitmapDeviceSharedPtr& rClip )
543 implDrawLine(rPt1,rPt2,rBounds,lineColor,
544 getMaskedIter(rClip),
545 maRawMaskedAccessor,
546 maRawMaskedXorAccessor,drawMode);
549 template< typename Iterator, typename RawAcc >
550 void implDrawPolygon( const basegfx::B2DPolygon& rPoly,
551 const basegfx::B2IBox& rBounds,
552 Color col,
553 const Iterator& begin,
554 const RawAcc& acc )
556 basegfx::B2DPolygon aPoly( rPoly );
557 if( rPoly.areControlPointsUsed() )
558 aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
560 const typename dest_iterator_type::value_type colorIndex( maColorLookup(
561 maAccessor,
562 col));
563 const sal_uInt32 nVertices( aPoly.count() );
564 for( sal_uInt32 i=1; i<nVertices; ++i )
565 implRenderLine2( basegfx::fround(aPoly.getB2DPoint(i-1)),
566 basegfx::fround(aPoly.getB2DPoint(i)),
567 rBounds,
568 colorIndex,
569 begin,
570 acc );
572 if( nVertices > 1 && aPoly.isClosed() )
573 implRenderLine2( basegfx::fround(aPoly.getB2DPoint(nVertices-1)),
574 basegfx::fround(aPoly.getB2DPoint(0)),
575 rBounds,
576 colorIndex,
577 begin,
578 acc );
581 virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
582 const basegfx::B2IBox& rBounds,
583 Color lineColor,
584 DrawMode drawMode )
586 if( drawMode == DrawMode_XOR )
587 implDrawPolygon( rPoly, rBounds, lineColor,
588 maBegin,
589 maRawXorAccessor );
590 else
591 implDrawPolygon( rPoly, rBounds, lineColor,
592 maBegin,
593 maRawAccessor );
596 virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
597 const basegfx::B2IBox& rBounds,
598 Color lineColor,
599 DrawMode drawMode,
600 const BitmapDeviceSharedPtr& rClip )
602 if( drawMode == DrawMode_XOR )
603 implDrawPolygon( rPoly, rBounds, lineColor,
604 getMaskedIter(rClip),
605 maRawMaskedXorAccessor );
606 else
607 implDrawPolygon( rPoly, rBounds, lineColor,
608 getMaskedIter(rClip),
609 maRawMaskedAccessor );
612 template< typename Iterator, typename RawAcc >
613 void implFillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
614 Color col,
615 const Iterator& begin,
616 const RawAcc& acc,
617 const basegfx::B2IBox& rBounds )
619 basegfx::B2DPolyPolygon aPoly( rPoly );
620 if( rPoly.areControlPointsUsed() )
621 aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
623 renderClippedPolyPolygon( begin,
624 acc,
625 maColorLookup( maAccessor,
626 col),
627 rBounds,
628 aPoly,
629 basegfx::FillRule_EVEN_ODD );
631 if( mpDamage )
633 basegfx::B2DRange const aPolyBounds( basegfx::tools::getRange(aPoly) );
634 damaged( basegfx::unotools::b2ISurroundingBoxFromB2DRange( aPolyBounds ) );
638 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
639 Color fillColor,
640 DrawMode drawMode,
641 const basegfx::B2IBox& rBounds )
643 if( drawMode == DrawMode_XOR )
644 implFillPolyPolygon( rPoly, fillColor,
645 maBegin,
646 maRawXorAccessor,
647 rBounds );
648 else
649 implFillPolyPolygon( rPoly, fillColor,
650 maBegin,
651 maRawAccessor,
652 rBounds );
655 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
656 Color fillColor,
657 DrawMode drawMode,
658 const basegfx::B2IBox& rBounds,
659 const BitmapDeviceSharedPtr& rClip )
661 if( drawMode == DrawMode_XOR )
662 implFillPolyPolygon( rPoly, fillColor,
663 getMaskedIter(rClip),
664 maRawMaskedXorAccessor,
665 rBounds );
666 else
667 implFillPolyPolygon( rPoly, fillColor,
668 getMaskedIter(rClip),
669 maRawMaskedAccessor,
670 rBounds );
673 template< typename Iterator, typename RawAcc >
674 void implDrawBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
675 const basegfx::B2IBox& rSrcRect,
676 const basegfx::B2IBox& rDstRect,
677 const Iterator& begin,
678 const RawAcc& acc)
680 boost::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
681 OSL_ASSERT( pSrcBmp );
683 scaleImage(
684 srcIterRange(pSrcBmp->maBegin,
685 pSrcBmp->maRawAccessor,
686 rSrcRect),
687 destIterRange(begin,
688 acc,
689 rDstRect),
690 rSrcBitmap.get() == this );
691 damaged( rDstRect );
694 template< typename Iterator, typename Acc >
695 void implDrawBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
696 const basegfx::B2IBox& rSrcRect,
697 const basegfx::B2IBox& rDstRect,
698 const Iterator& begin,
699 const Acc& acc)
701 GenericColorImageAccessor aSrcAcc( rSrcBitmap );
703 scaleImage(
704 srcIterRange(vigra::Diff2D(),
705 aSrcAcc,
706 rSrcRect),
707 destIterRange(begin,
708 acc,
709 rDstRect));
710 damaged( rDstRect );
713 virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
714 const basegfx::B2IBox& rSrcRect,
715 const basegfx::B2IBox& rDstRect,
716 DrawMode drawMode )
718 if( isCompatibleBitmap( rSrcBitmap ) )
720 if( drawMode == DrawMode_XOR )
721 implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
722 maBegin,
723 maRawXorAccessor);
724 else
725 implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
726 maBegin,
727 maRawAccessor);
729 else
731 if( drawMode == DrawMode_XOR )
732 implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
733 maBegin,
734 maXorAccessor);
735 else
736 implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
737 maBegin,
738 maAccessor);
740 damaged( rDstRect );
743 virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
744 const basegfx::B2IBox& rSrcRect,
745 const basegfx::B2IBox& rDstRect,
746 DrawMode drawMode,
747 const BitmapDeviceSharedPtr& rClip )
749 if( isCompatibleBitmap( rSrcBitmap ) )
751 if( drawMode == DrawMode_XOR )
752 implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
753 getMaskedIter(rClip),
754 maRawMaskedXorAccessor);
755 else
756 implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
757 getMaskedIter(rClip),
758 maRawMaskedAccessor);
760 else
762 if( drawMode == DrawMode_XOR )
763 implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
764 getMaskedIter(rClip),
765 maMaskedXorAccessor);
766 else
767 implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
768 getMaskedIter(rClip),
769 maMaskedAccessor);
771 damaged( rDstRect );
774 virtual void drawMaskedColor_i(Color aSrcColor,
775 const BitmapDeviceSharedPtr& rAlphaMask,
776 const basegfx::B2IBox& rSrcRect,
777 const basegfx::B2IPoint& rDstPoint )
779 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rAlphaMask) );
780 boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
782 if( pAlpha )
784 maColorBlendAccessor.setColor( aSrcColor );
786 vigra::copyImage( srcIterRange(pAlpha->maBegin,
787 pAlpha->maRawAccessor,
788 rSrcRect),
789 destIter(maBegin,
790 maColorBlendAccessor,
791 rDstPoint) );
793 else if( pMask )
795 const composite_iterator_type aBegin(
796 maBegin + vigra::Diff2D(rDstPoint.getX(),
797 rDstPoint.getY()),
798 pMask->maBegin + topLeft(rSrcRect) );
800 fillImage(aBegin,
801 aBegin + vigra::Diff2D(rSrcRect.getWidth(),
802 rSrcRect.getHeight()),
803 maRawMaskedAccessor,
804 maColorLookup(
805 maAccessor,
806 aSrcColor) );
808 else
810 GenericColorImageAccessor aSrcAcc( rAlphaMask );
811 maGenericColorBlendAccessor.setColor( aSrcColor );
813 vigra::copyImage( srcIterRange(vigra::Diff2D(),
814 aSrcAcc,
815 rSrcRect),
816 destIter(maBegin,
817 maGenericColorBlendAccessor,
818 rDstPoint) );
820 damagedPointSize( rDstPoint, rSrcRect );
823 virtual void drawMaskedColor_i(Color aSrcColor,
824 const BitmapDeviceSharedPtr& rAlphaMask,
825 const basegfx::B2IBox& rSrcRect,
826 const basegfx::B2IPoint& rDstPoint,
827 const BitmapDeviceSharedPtr& rClip )
829 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rAlphaMask) );
830 boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
832 if( pAlpha )
834 const composite_iterator_type aBegin( getMaskedIter(rClip) );
835 maMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
836 aSrcColor );
838 vigra::copyImage( srcIterRange(pAlpha->maBegin,
839 pAlpha->maRawAccessor,
840 rSrcRect),
841 destIter(aBegin,
842 maMaskedColorBlendAccessor,
843 rDstPoint) );
845 else if( pMask )
847 boost::shared_ptr<mask_bitmap_type> pClipMask( getCompatibleClipMask(rClip) );
848 OSL_ASSERT( pClipMask );
850 // setup a ((iter,mask),clipMask) composite composite
851 // iterator, to pass both masks (clip and alpha mask)
852 // to the algorithm
853 const composite_composite_mask_iterator_type aBegin(
854 composite_iterator_type(
855 maBegin + vigra::Diff2D(rDstPoint.getX(),
856 rDstPoint.getY()),
857 pMask->maBegin + topLeft(rSrcRect)),
858 pClipMask->maBegin + vigra::Diff2D(rDstPoint.getX(),
859 rDstPoint.getY()) );
861 fillImage(aBegin,
862 aBegin + vigra::Diff2D(rSrcRect.getWidth(),
863 rSrcRect.getHeight()),
864 maRawMaskedMaskAccessor,
865 maColorLookup(
866 maAccessor,
867 aSrcColor) );
869 else
871 GenericColorImageAccessor aSrcAcc( rAlphaMask );
872 const composite_iterator_type aBegin( getMaskedIter(rClip) );
873 maGenericMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
874 aSrcColor );
876 vigra::copyImage( srcIterRange(vigra::Diff2D(),
877 aSrcAcc,
878 rSrcRect),
879 destIter(aBegin,
880 maGenericMaskedColorBlendAccessor,
881 rDstPoint) );
883 damagedPointSize( rDstPoint, rSrcRect );
886 template< typename Iterator, typename Acc >
887 void implDrawMaskedBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
888 const BitmapDeviceSharedPtr& rMask,
889 const basegfx::B2IBox& rSrcRect,
890 const basegfx::B2IBox& rDstRect,
891 const Iterator& begin,
892 const Acc& acc)
894 boost::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
895 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rMask) );
896 OSL_ASSERT( pMask && pSrcBmp );
898 scaleImage(
899 srcIterRange(composite_iterator_type(
900 pSrcBmp->maBegin,
901 pMask->maBegin),
902 joined_image_accessor_type(
903 pSrcBmp->maAccessor,
904 pMask->maRawAccessor),
905 rSrcRect),
906 destIterRange(begin,
907 typename masked_input_splitting_accessor<
908 Acc,
909 joined_image_accessor_type,
910 Masks::clipmask_polarity,
911 FastMask >::type(acc),
912 rDstRect),
913 rSrcBitmap.get() == this);
914 damaged( rDstRect );
917 template< typename Iterator, typename Acc >
918 void implDrawMaskedBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
919 const BitmapDeviceSharedPtr& rMask,
920 const basegfx::B2IBox& rSrcRect,
921 const basegfx::B2IBox& rDstRect,
922 const Iterator& begin,
923 const Acc& acc)
925 GenericColorImageAccessor aSrcAcc( rSrcBitmap );
926 GenericColorImageAccessor aMaskAcc( rMask );
928 const vigra::Diff2D aTopLeft(rSrcRect.getMinX(),
929 rSrcRect.getMinY());
930 const vigra::Diff2D aBottomRight(rSrcRect.getMaxX(),
931 rSrcRect.getMaxY());
932 scaleImage(
933 vigra::make_triple(
934 generic_composite_iterator_type(
935 aTopLeft,aTopLeft),
936 generic_composite_iterator_type(
937 aBottomRight,aBottomRight),
938 joined_generic_image_accessor_type(
939 aSrcAcc,
940 aMaskAcc)),
941 destIterRange(begin,
942 typename masked_input_splitting_accessor<
943 Acc,
944 joined_generic_image_accessor_type,
945 Masks::clipmask_polarity,
946 NoFastMask >::type(acc),
947 rDstRect));
948 damaged( rDstRect );
951 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
952 const BitmapDeviceSharedPtr& rMask,
953 const basegfx::B2IBox& rSrcRect,
954 const basegfx::B2IBox& rDstRect,
955 DrawMode drawMode )
957 if( isCompatibleClipMask(rMask) &&
958 isCompatibleBitmap(rSrcBitmap) )
960 if( drawMode == DrawMode_XOR )
961 implDrawMaskedBitmap(rSrcBitmap, rMask,
962 rSrcRect, rDstRect,
963 maBegin,
964 maXorAccessor);
965 else
966 implDrawMaskedBitmap(rSrcBitmap, rMask,
967 rSrcRect, rDstRect,
968 maBegin,
969 maAccessor);
971 else
973 if( drawMode == DrawMode_XOR )
974 implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
975 rSrcRect, rDstRect,
976 maBegin,
977 maXorAccessor);
978 else
979 implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
980 rSrcRect, rDstRect,
981 maBegin,
982 maAccessor);
984 damaged( rDstRect );
987 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
988 const BitmapDeviceSharedPtr& rMask,
989 const basegfx::B2IBox& rSrcRect,
990 const basegfx::B2IBox& rDstRect,
991 DrawMode drawMode,
992 const BitmapDeviceSharedPtr& rClip )
994 if( isCompatibleClipMask(rMask) &&
995 isCompatibleBitmap(rSrcBitmap) )
997 if( drawMode == DrawMode_XOR )
998 implDrawMaskedBitmap(rSrcBitmap, rMask,
999 rSrcRect, rDstRect,
1000 getMaskedIter(rClip),
1001 maMaskedXorAccessor);
1002 else
1003 implDrawMaskedBitmap(rSrcBitmap, rMask,
1004 rSrcRect, rDstRect,
1005 getMaskedIter(rClip),
1006 maMaskedAccessor);
1008 else
1010 if( drawMode == DrawMode_XOR )
1011 implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
1012 rSrcRect, rDstRect,
1013 getMaskedIter(rClip),
1014 maMaskedXorAccessor);
1015 else
1016 implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
1017 rSrcRect, rDstRect,
1018 getMaskedIter(rClip),
1019 maMaskedAccessor);
1021 damaged( rDstRect );
1024 IBitmapDeviceDamageTrackerSharedPtr getDamageTracker_i() const
1026 return mpDamage;
1028 void setDamageTracker_i( const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
1030 mpDamage = rDamage;
1033 } // namespace
1035 struct ImplBitmapDevice
1037 /** Bitmap memory plus deleter.
1039 Always points to the start of the mem
1041 RawMemorySharedArray mpMem;
1043 /// Palette memory plus deleter (might be NULL)
1044 PaletteMemorySharedVector mpPalette;
1046 /** Bounds of the device.
1048 maBounds.getWidth()/getHeight() yield the true size of the
1049 device (i.e. the rectangle given by maBounds covers the device
1050 area under the including-the-bottommost-and-rightmost-pixels
1051 fill rule)
1053 basegfx::B2IBox maBounds;
1055 /// Scanline format, as provided at the constructor
1056 sal_Int32 mnScanlineFormat;
1058 /// Scanline stride. Negative for bottom-to-top formats
1059 sal_Int32 mnScanlineStride;
1061 /// raw ptr to 0th scanline. used for cloning a generic renderer
1062 sal_uInt8* mpFirstScanline;
1064 /** (Optional) device sharing the same memory, and used for input
1065 clip masks/alpha masks/bitmaps that don't match our exact
1066 bitmap format.
1068 This is to avoid the combinatorical explosion when dealing
1069 with n bitmap formats, which could be combined with n clip
1070 masks, alpha masks and bitmap masks (yielding a total of n^4
1071 combinations). Since each BitmapRenderer is specialized for
1072 one specific combination of said formats, a lot of duplicate
1073 code would be generated, most of which probably never
1074 used. Therefore, only the most common combinations are
1075 specialized templates, the remainder gets handled by this
1076 generic renderer (via runtime polymorphism).
1078 BitmapDeviceSharedPtr mpGenericRenderer;
1082 BitmapDevice::BitmapDevice( const basegfx::B2IBox& rBounds,
1083 sal_Int32 nScanlineFormat,
1084 sal_Int32 nScanlineStride,
1085 sal_uInt8* pFirstScanline,
1086 const RawMemorySharedArray& rMem,
1087 const PaletteMemorySharedVector& rPalette ) :
1088 mpImpl( new ImplBitmapDevice )
1090 mpImpl->mpMem = rMem;
1091 mpImpl->mpPalette = rPalette;
1092 mpImpl->maBounds = rBounds;
1093 mpImpl->mnScanlineFormat = nScanlineFormat;
1094 mpImpl->mnScanlineStride = nScanlineStride;
1095 mpImpl->mpFirstScanline = pFirstScanline;
1098 BitmapDevice::~BitmapDevice()
1100 // outline, because of internal ImplBitmapDevice
1103 basegfx::B2IVector BitmapDevice::getSize() const
1105 return basegfx::B2IVector(
1106 mpImpl->maBounds.getMaxX() - mpImpl->maBounds.getMinX(),
1107 mpImpl->maBounds.getMaxY() - mpImpl->maBounds.getMinY() );
1110 bool BitmapDevice::isTopDown() const
1112 return mpImpl->mnScanlineStride >= 0;
1115 sal_Int32 BitmapDevice::getScanlineFormat() const
1117 return mpImpl->mnScanlineFormat;
1120 sal_Int32 BitmapDevice::getScanlineStride() const
1122 return mpImpl->mnScanlineStride < 0 ?
1123 -mpImpl->mnScanlineStride : mpImpl->mnScanlineStride;
1126 RawMemorySharedArray BitmapDevice::getBuffer() const
1128 return mpImpl->mpMem;
1131 IBitmapDeviceDamageTrackerSharedPtr BitmapDevice::getDamageTracker() const
1133 return getDamageTracker_i();
1136 void BitmapDevice::setDamageTracker( const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
1138 setDamageTracker_i(rDamage);
1141 PaletteMemorySharedVector BitmapDevice::getPalette() const
1143 return mpImpl->mpPalette;
1146 void BitmapDevice::clear( Color fillColor )
1148 clear_i( fillColor, mpImpl->maBounds );
1151 void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
1152 Color lineColor,
1153 DrawMode drawMode )
1155 if( mpImpl->maBounds.isInside(rPt) )
1156 setPixel_i(rPt,lineColor,drawMode);
1159 void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
1160 Color lineColor,
1161 DrawMode drawMode,
1162 const BitmapDeviceSharedPtr& rClip )
1164 if( !rClip )
1166 setPixel(rPt,lineColor,drawMode);
1167 return;
1170 if( mpImpl->maBounds.isInside(rPt) )
1172 if( isCompatibleClipMask( rClip ) )
1173 setPixel_i(rPt,lineColor,drawMode,rClip);
1174 else
1175 getGenericRenderer()->setPixel( rPt, lineColor, drawMode, rClip );
1179 Color BitmapDevice::getPixel( const basegfx::B2IPoint& rPt )
1181 if( mpImpl->maBounds.isInside(rPt) )
1182 return getPixel_i(rPt);
1184 return Color();
1187 sal_uInt32 BitmapDevice::getPixelData( const basegfx::B2IPoint& rPt )
1189 if( mpImpl->maBounds.isInside(rPt) )
1190 return getPixelData_i(rPt);
1192 return 0;
1195 void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
1196 const basegfx::B2IPoint& rPt2,
1197 Color lineColor,
1198 DrawMode drawMode )
1200 drawLine_i( rPt1,
1201 rPt2,
1202 mpImpl->maBounds,
1203 lineColor,
1204 drawMode );
1207 void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
1208 const basegfx::B2IPoint& rPt2,
1209 Color lineColor,
1210 DrawMode drawMode,
1211 const BitmapDeviceSharedPtr& rClip )
1213 if( !rClip )
1215 drawLine(rPt1,rPt2,lineColor,drawMode);
1216 return;
1219 if( isCompatibleClipMask( rClip ) )
1220 drawLine_i( rPt1,
1221 rPt2,
1222 mpImpl->maBounds,
1223 lineColor,
1224 drawMode,
1225 rClip );
1226 else
1227 getGenericRenderer()->drawLine( rPt1, rPt2, lineColor,
1228 drawMode, rClip );
1231 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
1232 Color lineColor,
1233 DrawMode drawMode )
1235 const sal_uInt32 numVertices( rPoly.count() );
1236 if( numVertices )
1237 drawPolygon_i( rPoly,
1238 mpImpl->maBounds,
1239 lineColor, drawMode );
1242 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
1243 Color lineColor,
1244 DrawMode drawMode,
1245 const BitmapDeviceSharedPtr& rClip )
1247 if( !rClip )
1249 drawPolygon(rPoly,lineColor,drawMode);
1250 return;
1253 const sal_uInt32 numVertices( rPoly.count() );
1254 if( numVertices )
1256 if( isCompatibleClipMask( rClip ) )
1257 drawPolygon_i( rPoly,
1258 mpImpl->maBounds,
1259 lineColor, drawMode, rClip );
1260 else
1261 getGenericRenderer()->drawPolygon( rPoly, lineColor,
1262 drawMode, rClip );
1266 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
1267 Color fillColor,
1268 DrawMode drawMode )
1270 fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds );
1273 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
1274 Color fillColor,
1275 DrawMode drawMode,
1276 const BitmapDeviceSharedPtr& rClip )
1278 if( !rClip )
1280 fillPolyPolygon(rPoly,fillColor,drawMode);
1281 return;
1284 if( isCompatibleClipMask( rClip ) )
1285 fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds, rClip );
1286 else
1287 getGenericRenderer()->fillPolyPolygon( rPoly, fillColor,
1288 drawMode, rClip );
1292 namespace
1294 void assertImagePoint( const basegfx::B2IPoint& rPt,
1295 const basegfx::B2IBox& rPermittedRange )
1297 (void)rPt; (void)rPermittedRange;
1298 OSL_ASSERT( rPermittedRange.isInside(rPt) );
1301 void assertImageRange( const basegfx::B2IBox& rRange,
1302 const basegfx::B2IBox& rPermittedRange )
1304 #if OSL_DEBUG_LEVEL > 0
1305 basegfx::B2IBox aRange( rRange );
1306 aRange.intersect( rPermittedRange );
1308 OSL_ASSERT( aRange == rRange );
1309 #else
1310 (void)rRange; (void)rPermittedRange;
1311 #endif
1314 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1315 // to basegfx, and use here!
1316 bool clipAreaImpl( ::basegfx::B2IBox& io_rSourceArea,
1317 ::basegfx::B2IPoint& io_rDestPoint,
1318 const ::basegfx::B2IBox& rSourceBounds,
1319 const ::basegfx::B2IBox& rDestBounds )
1321 const ::basegfx::B2IPoint aSourceTopLeft(
1322 io_rSourceArea.getMinimum() );
1324 ::basegfx::B2IBox aLocalSourceArea( io_rSourceArea );
1326 // clip source area (which must be inside rSourceBounds)
1327 aLocalSourceArea.intersect( rSourceBounds );
1329 if( aLocalSourceArea.isEmpty() )
1330 return false;
1332 // calc relative new source area points (relative to orig
1333 // source area)
1334 const ::basegfx::B2IVector aUpperLeftOffset(
1335 aLocalSourceArea.getMinimum()-aSourceTopLeft );
1336 const ::basegfx::B2IVector aLowerRightOffset(
1337 aLocalSourceArea.getMaximum()-aSourceTopLeft );
1339 ::basegfx::B2IBox aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
1340 io_rDestPoint + aLowerRightOffset );
1342 // clip dest area (which must be inside rDestBounds)
1343 aLocalDestArea.intersect( rDestBounds );
1345 if( aLocalDestArea.isEmpty() )
1346 return false;
1348 // calc relative new dest area points (relative to orig
1349 // source area)
1350 const ::basegfx::B2IVector aDestUpperLeftOffset(
1351 aLocalDestArea.getMinimum()-io_rDestPoint );
1352 const ::basegfx::B2IVector aDestLowerRightOffset(
1353 aLocalDestArea.getMaximum()-io_rDestPoint );
1355 io_rSourceArea = ::basegfx::B2IBox( aSourceTopLeft + aDestUpperLeftOffset,
1356 aSourceTopLeft + aDestLowerRightOffset );
1357 io_rDestPoint = aLocalDestArea.getMinimum();
1359 return true;
1362 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1363 // to basegfx, and use here!
1364 bool clipAreaImpl( ::basegfx::B2IBox& io_rDestArea,
1365 ::basegfx::B2IBox& io_rSourceArea,
1366 const ::basegfx::B2IBox& rDestBounds,
1367 const ::basegfx::B2IBox& rSourceBounds )
1369 // extract inherent scale
1370 const double nScaleX( io_rDestArea.getWidth() / (double)io_rSourceArea.getWidth() );
1371 const double nScaleY( io_rDestArea.getHeight() / (double)io_rSourceArea.getHeight() );
1373 // extract range origins
1374 const basegfx::B2IPoint aDestTopLeft(
1375 io_rDestArea.getMinimum() );
1376 const ::basegfx::B2IPoint aSourceTopLeft(
1377 io_rSourceArea.getMinimum() );
1379 ::basegfx::B2IBox aLocalSourceArea( io_rSourceArea );
1381 // clip source area (which must be inside rSourceBounds)
1382 aLocalSourceArea.intersect( rSourceBounds );
1384 if( aLocalSourceArea.isEmpty() )
1385 return false;
1387 // calc relative new source area points (relative to orig
1388 // source area)
1389 const ::basegfx::B2IVector aUpperLeftOffset(
1390 aLocalSourceArea.getMinimum()-aSourceTopLeft );
1391 const ::basegfx::B2IVector aLowerRightOffset(
1392 aLocalSourceArea.getMaximum()-aSourceTopLeft );
1394 ::basegfx::B2IBox aLocalDestArea( basegfx::fround(aDestTopLeft.getX() + nScaleX*aUpperLeftOffset.getX()),
1395 basegfx::fround(aDestTopLeft.getY() + nScaleY*aUpperLeftOffset.getY()),
1396 basegfx::fround(aDestTopLeft.getX() + nScaleX*aLowerRightOffset.getX()),
1397 basegfx::fround(aDestTopLeft.getY() + nScaleY*aLowerRightOffset.getY()) );
1399 // clip dest area (which must be inside rDestBounds)
1400 aLocalDestArea.intersect( rDestBounds );
1402 if( aLocalDestArea.isEmpty() )
1403 return false;
1405 // calc relative new dest area points (relative to orig
1406 // source area)
1407 const ::basegfx::B2IVector aDestUpperLeftOffset(
1408 aLocalDestArea.getMinimum()-aDestTopLeft );
1409 const ::basegfx::B2IVector aDestLowerRightOffset(
1410 aLocalDestArea.getMaximum()-aDestTopLeft );
1412 io_rSourceArea = ::basegfx::B2IBox( basegfx::fround(aSourceTopLeft.getX() + aDestUpperLeftOffset.getX()/nScaleX),
1413 basegfx::fround(aSourceTopLeft.getY() + aDestUpperLeftOffset.getY()/nScaleY),
1414 basegfx::fround(aSourceTopLeft.getX() + aDestLowerRightOffset.getX()/nScaleX),
1415 basegfx::fround(aSourceTopLeft.getY() + aDestLowerRightOffset.getY()/nScaleY) );
1416 io_rDestArea = aLocalDestArea;
1418 // final source area clip (chopping round-offs)
1419 io_rSourceArea.intersect( rSourceBounds );
1421 if( io_rSourceArea.isEmpty() )
1422 return false;
1425 return true;
1429 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1430 const basegfx::B2IBox& rSrcRect,
1431 const basegfx::B2IBox& rDstRect,
1432 DrawMode drawMode )
1434 const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1435 const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1436 basegfx::B2IBox aSrcRange( rSrcRect );
1437 basegfx::B2IBox aDestRange( rDstRect );
1439 if( clipAreaImpl( aDestRange,
1440 aSrcRange,
1441 mpImpl->maBounds,
1442 aSrcBounds ))
1444 assertImageRange(aDestRange,mpImpl->maBounds);
1445 assertImageRange(aSrcRange,aSrcBounds);
1447 drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode );
1451 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1452 const basegfx::B2IBox& rSrcRect,
1453 const basegfx::B2IBox& rDstRect,
1454 DrawMode drawMode,
1455 const BitmapDeviceSharedPtr& rClip )
1457 if( !rClip )
1459 drawBitmap(rSrcBitmap,rSrcRect,rDstRect,drawMode);
1460 return;
1463 const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1464 const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1465 basegfx::B2IBox aSrcRange( rSrcRect );
1466 basegfx::B2IBox aDestRange( rDstRect );
1468 if( clipAreaImpl( aDestRange,
1469 aSrcRange,
1470 mpImpl->maBounds,
1471 aSrcBounds ))
1473 assertImageRange(aDestRange,mpImpl->maBounds);
1474 assertImageRange(aSrcRange,aSrcBounds);
1476 if( isCompatibleClipMask( rClip ) )
1478 drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode, rClip );
1480 else
1482 getGenericRenderer()->drawBitmap( rSrcBitmap, rSrcRect,
1483 rDstRect, drawMode, rClip );
1488 void BitmapDevice::drawMaskedColor( Color aSrcColor,
1489 const BitmapDeviceSharedPtr& rAlphaMask,
1490 const basegfx::B2IBox& rSrcRect,
1491 const basegfx::B2IPoint& rDstPoint )
1493 const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
1494 const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1495 basegfx::B2IBox aSrcRange( rSrcRect );
1496 basegfx::B2IPoint aDestPoint( rDstPoint );
1498 if( clipAreaImpl( aSrcRange,
1499 aDestPoint,
1500 aSrcBounds,
1501 mpImpl->maBounds ))
1503 assertImagePoint(aDestPoint,mpImpl->maBounds);
1504 assertImageRange(aSrcRange,aSrcBounds);
1506 if( rAlphaMask.get() == this )
1508 // src == dest, copy rAlphaMask beforehand
1509 // ---------------------------------------------------
1511 const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
1512 aSrcRange.getHeight() );
1513 BitmapDeviceSharedPtr pAlphaCopy(
1514 cloneBitmapDevice( aSize,
1515 shared_from_this()) );
1516 basegfx::B2ITuple aGcc3WorkaroundTemporary;
1517 const basegfx::B2IBox aAlphaRange( aGcc3WorkaroundTemporary,
1518 aSize );
1519 pAlphaCopy->drawBitmap(rAlphaMask,
1520 aSrcRange,
1521 aAlphaRange,
1522 DrawMode_PAINT);
1523 drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint );
1525 else
1527 drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint );
1532 void BitmapDevice::drawMaskedColor( Color aSrcColor,
1533 const BitmapDeviceSharedPtr& rAlphaMask,
1534 const basegfx::B2IBox& rSrcRect,
1535 const basegfx::B2IPoint& rDstPoint,
1536 const BitmapDeviceSharedPtr& rClip )
1538 if( !rClip )
1540 drawMaskedColor(aSrcColor,rAlphaMask,rSrcRect,rDstPoint);
1541 return;
1544 const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
1545 const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1546 basegfx::B2IBox aSrcRange( rSrcRect );
1547 basegfx::B2IPoint aDestPoint( rDstPoint );
1549 if( clipAreaImpl( aSrcRange,
1550 aDestPoint,
1551 aSrcBounds,
1552 mpImpl->maBounds ))
1554 assertImagePoint(aDestPoint,mpImpl->maBounds);
1555 assertImageRange(aSrcRange,aSrcBounds);
1557 if( isCompatibleClipMask( rClip ) )
1559 if( rAlphaMask.get() == this )
1561 // src == dest, copy rAlphaMask beforehand
1562 // ---------------------------------------------------
1564 const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
1565 aSrcRange.getHeight() );
1566 BitmapDeviceSharedPtr pAlphaCopy(
1567 cloneBitmapDevice( aSize,
1568 shared_from_this()) );
1569 basegfx::B2ITuple aGcc3WorkaroundTemporary;
1570 const basegfx::B2IBox aAlphaRange( aGcc3WorkaroundTemporary,
1571 aSize );
1572 pAlphaCopy->drawBitmap(rAlphaMask,
1573 aSrcRange,
1574 aAlphaRange,
1575 DrawMode_PAINT);
1576 drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint, rClip );
1578 else
1580 drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint, rClip );
1583 else
1585 getGenericRenderer()->drawMaskedColor( aSrcColor, rAlphaMask,
1586 rSrcRect, rDstPoint, rClip );
1591 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1592 const BitmapDeviceSharedPtr& rMask,
1593 const basegfx::B2IBox& rSrcRect,
1594 const basegfx::B2IBox& rDstRect,
1595 DrawMode drawMode )
1597 OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
1599 const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1600 const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1601 basegfx::B2IBox aSrcRange( rSrcRect );
1602 basegfx::B2IBox aDestRange( rDstRect );
1604 if( clipAreaImpl( aDestRange,
1605 aSrcRange,
1606 mpImpl->maBounds,
1607 aSrcBounds ))
1609 assertImageRange(aDestRange,mpImpl->maBounds);
1610 assertImageRange(aSrcRange,aSrcBounds);
1612 drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode );
1616 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1617 const BitmapDeviceSharedPtr& rMask,
1618 const basegfx::B2IBox& rSrcRect,
1619 const basegfx::B2IBox& rDstRect,
1620 DrawMode drawMode,
1621 const BitmapDeviceSharedPtr& rClip )
1623 if( !rClip )
1625 drawMaskedBitmap(rSrcBitmap,rMask,rSrcRect,rDstRect,drawMode);
1626 return;
1629 OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
1631 const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1632 const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1633 basegfx::B2IBox aSrcRange( rSrcRect );
1634 basegfx::B2IBox aDestRange( rDstRect );
1636 if( clipAreaImpl( aDestRange,
1637 aSrcRange,
1638 mpImpl->maBounds,
1639 aSrcBounds ))
1641 assertImageRange(aDestRange,mpImpl->maBounds);
1642 assertImageRange(aSrcRange,aSrcBounds);
1644 if( isCompatibleClipMask( rClip ) )
1646 drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode, rClip );
1648 else
1650 getGenericRenderer()->drawMaskedBitmap( rSrcBitmap, rMask, rSrcRect,
1651 rDstRect, drawMode, rClip );
1657 //----------------------------------------------------------------------------------
1659 /** Standard clip and alpha masks
1661 struct StdMasks
1663 typedef PixelFormatTraits_GREY1_MSB clipmask_format_traits;
1664 typedef PixelFormatTraits_GREY8 alphamask_format_traits;
1666 /// Clipmask: 0 means opaque
1667 static const bool clipmask_polarity = false;
1669 /// Alpha mask: 0 means fully transparent
1670 static const bool alphamask_polarity = true;
1673 //----------------------------------------------------------------------------------
1675 // Some compilers don't like the nested template wrap_accessor
1676 // reference in the parameter list - being slightly less type safe,
1677 // then.
1678 #ifndef BASEBMP_NO_NESTED_TEMPLATE_PARAMETER
1680 /// Produces a specialized renderer for the given pixel format
1681 template< class FormatTraits, class MaskTraits >
1682 BitmapDeviceSharedPtr createRenderer(
1683 const basegfx::B2IBox& rBounds,
1684 sal_Int32 nScanlineFormat,
1685 sal_Int32 nScanlineStride,
1686 sal_uInt8* pFirstScanline,
1687 typename FormatTraits::raw_accessor_type const& rRawAccessor,
1688 typename FormatTraits::accessor_selector::template wrap_accessor<
1689 typename FormatTraits::raw_accessor_type>::type const& rAccessor,
1690 boost::shared_array< sal_uInt8 > pMem,
1691 const PaletteMemorySharedVector& pPal,
1692 const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
1693 #else
1695 template< class FormatTraits, class MaskTraits, class Accessor >
1696 BitmapDeviceSharedPtr createRenderer(
1697 const basegfx::B2IBox& rBounds,
1698 sal_Int32 nScanlineFormat,
1699 sal_Int32 nScanlineStride,
1700 sal_uInt8* pFirstScanline,
1701 typename FormatTraits::raw_accessor_type const& rRawAccessor,
1702 Accessor const& rAccessor,
1703 boost::shared_array< sal_uInt8 > pMem,
1704 const PaletteMemorySharedVector& pPal,
1705 const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
1707 #endif
1709 typedef typename FormatTraits::iterator_type Iterator;
1710 typedef BitmapRenderer< Iterator,
1711 typename FormatTraits::raw_accessor_type,
1712 typename FormatTraits::accessor_selector,
1713 MaskTraits > Renderer;
1715 return BitmapDeviceSharedPtr(
1716 new Renderer( rBounds,
1717 nScanlineFormat,
1718 nScanlineStride,
1719 pFirstScanline,
1720 Iterator(
1721 reinterpret_cast<typename Iterator::value_type*>(
1722 pFirstScanline),
1723 nScanlineStride),
1724 rRawAccessor,
1725 rAccessor,
1726 pMem,
1727 pPal,
1728 pDamage ));
1731 /// Create standard grey level palette
1732 PaletteMemorySharedVector createStandardPalette(
1733 const PaletteMemorySharedVector& pPal,
1734 sal_Int32 nNumEntries )
1736 if( pPal || nNumEntries <= 0 )
1737 return pPal;
1739 boost::shared_ptr< std::vector<Color> > pLocalPal(
1740 new std::vector<Color>(nNumEntries) );
1742 const sal_Int32 nIncrement( 0x00FFFFFF/nNumEntries );
1743 --nNumEntries;
1744 for( sal_Int32 i=0, c=0; i<nNumEntries; ++i,c+=nIncrement )
1745 pLocalPal->at(i) = Color(0xFF000000 | c);
1747 pLocalPal->at(nNumEntries) = Color(0xFFFFFFFF);
1749 return pLocalPal;
1752 template< class FormatTraits, class MaskTraits >
1753 BitmapDeviceSharedPtr createRenderer(
1754 const basegfx::B2IBox& rBounds,
1755 sal_Int32 nScanlineFormat,
1756 sal_Int32 nScanlineStride,
1757 sal_uInt8* pFirstScanline,
1758 boost::shared_array< sal_uInt8 > pMem,
1759 const PaletteMemorySharedVector& pPal,
1760 const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
1762 return createRenderer<FormatTraits,
1763 MaskTraits>(rBounds,
1764 nScanlineFormat,
1765 nScanlineStride,
1766 pFirstScanline,
1767 typename FormatTraits::raw_accessor_type(),
1768 typename FormatTraits::accessor_selector::template
1769 wrap_accessor<
1770 typename FormatTraits::raw_accessor_type>::type(),
1771 pMem,
1772 pPal,
1773 pDamage);
1776 template< class FormatTraits, class MaskTraits >
1777 BitmapDeviceSharedPtr createRenderer(
1778 const basegfx::B2IBox& rBounds,
1779 sal_Int32 nScanlineFormat,
1780 sal_Int32 nScanlineStride,
1781 sal_uInt8* pFirstScanline,
1782 boost::shared_array< sal_uInt8 > pMem,
1783 PaletteMemorySharedVector pPal,
1784 int nBitsPerPixel,
1785 const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
1787 pPal = createStandardPalette(pPal,
1788 1UL << nBitsPerPixel);
1790 OSL_ASSERT(pPal);
1791 return createRenderer<FormatTraits,
1792 MaskTraits>(rBounds,
1793 nScanlineFormat,
1794 nScanlineStride,
1795 pFirstScanline,
1796 typename FormatTraits::raw_accessor_type(),
1797 typename FormatTraits::accessor_selector::template
1798 wrap_accessor<
1799 typename FormatTraits::raw_accessor_type>::type(
1800 &pPal->at(0),
1801 pPal->size()),
1802 pMem,
1803 pPal,
1804 pDamage);
1807 //----------------------------------------------------------------------------------
1809 // TODO(Q3): consolidate with canvas/canvastools.hxx! Best move this
1810 // to o3tl or sal/bithacks.hxx ...
1812 /** Compute the next highest power of 2 of a 32-bit value
1814 Code devised by Sean Anderson, in good ole HAKMEM
1815 tradition.
1817 @return 1 << (lg(x - 1) + 1)
1819 inline sal_uInt32 nextPow2( sal_uInt32 x )
1821 --x;
1822 x |= x >> 1;
1823 x |= x >> 2;
1824 x |= x >> 4;
1825 x |= x >> 8;
1826 x |= x >> 16;
1828 return ++x;
1831 //----------------------------------------------------------------------------------
1833 namespace
1835 BitmapDeviceSharedPtr createBitmapDeviceImpl( const basegfx::B2IVector& rSize,
1836 bool bTopDown,
1837 sal_Int32 nScanlineFormat,
1838 boost::shared_array< sal_uInt8 > pMem,
1839 PaletteMemorySharedVector pPal,
1840 const basegfx::B2IBox* pSubset,
1841 const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
1843 OSL_ASSERT(rSize.getX() > 0 && rSize.getY() > 0);
1845 if( nScanlineFormat <= Format::NONE ||
1846 nScanlineFormat > Format::MAX )
1847 return BitmapDeviceSharedPtr();
1849 static const sal_uInt8 bitsPerPixel[] =
1851 0, // NONE
1852 1, // ONE_BIT_MSB_GREY
1853 1, // ONE_BIT_LSB_GREY
1854 1, // ONE_BIT_MSB_PAL
1855 1, // ONE_BIT_LSB_PAL
1856 4, // FOUR_BIT_MSB_GREY
1857 4, // FOUR_BIT_LSB_GREY
1858 4, // FOUR_BIT_MSB_PAL
1859 4, // FOUR_BIT_LSB_PAL
1860 8, // EIGHT_BIT_PAL
1861 8, // EIGHT_BIT_GREY
1862 16, // SIXTEEN_BIT_LSB_TC_MASK
1863 16, // SIXTEEN_BIT_MSB_TC_MASK
1864 24, // TWENTYFOUR_BIT_TC_MASK
1865 32, // THIRTYTWO_BIT_TC_MASK
1866 32, // THIRTYTWO_BIT_TC_MASK_ARGB
1869 sal_Int32 nScanlineStride(0);
1871 // round up to full 8 bit, divide by 8
1872 nScanlineStride = (rSize.getX()*bitsPerPixel[nScanlineFormat] + 7) >> 3;
1874 // rounded up to next full power-of-two number of bytes
1875 const sal_uInt32 bytesPerPixel = nextPow2(
1876 (bitsPerPixel[nScanlineFormat] + 7) >> 3);
1878 // now make nScanlineStride a multiple of bytesPerPixel
1879 nScanlineStride = (nScanlineStride + bytesPerPixel - 1) / bytesPerPixel * bytesPerPixel;
1881 // factor in bottom-up scanline order case
1882 nScanlineStride *= bTopDown ? 1 : -1;
1884 const sal_uInt32 nWidth(nScanlineStride < 0 ? -nScanlineStride : nScanlineStride);
1885 const sal_uInt32 nHeight(rSize.getY());
1887 if (nHeight && nWidth && nWidth > SAL_MAX_INT32 / nHeight)
1889 SAL_WARN( "basebmp", "suspicious massive alloc " << nWidth << " * " << nHeight);
1890 return BitmapDeviceSharedPtr();
1893 const std::size_t nMemSize(nWidth * nHeight);
1895 if( !pMem )
1897 pMem.reset(
1898 reinterpret_cast<sal_uInt8*>(rtl_allocateMemory( nMemSize )),
1899 &rtl_freeMemory );
1900 if (pMem.get() == 0 && nMemSize != 0)
1901 return BitmapDeviceSharedPtr();
1902 rtl_zeroMemory(pMem.get(),nMemSize);
1905 sal_uInt8* pFirstScanline = nScanlineStride < 0 ?
1906 pMem.get() + nMemSize + nScanlineStride : pMem.get();
1908 // shrink render area to given subset, if given
1909 basegfx::B2IBox aBounds(0,0,rSize.getX(),rSize.getY());
1910 if( pSubset )
1911 aBounds.intersect( *pSubset );
1913 switch( nScanlineFormat )
1915 // ----------------------------------------------------------------------
1916 // one bit formats
1918 case Format::ONE_BIT_MSB_GREY:
1919 return createRenderer<PixelFormatTraits_GREY1_MSB,StdMasks>(
1920 aBounds, nScanlineFormat, nScanlineStride,
1921 pFirstScanline, pMem, pPal, rDamage );
1923 case Format::ONE_BIT_LSB_GREY:
1924 return createRenderer<PixelFormatTraits_GREY1_LSB,StdMasks>(
1925 aBounds, nScanlineFormat, nScanlineStride,
1926 pFirstScanline, pMem, pPal, rDamage );
1928 case Format::ONE_BIT_MSB_PAL:
1929 return createRenderer<PixelFormatTraits_PAL1_MSB,StdMasks>(
1930 aBounds, nScanlineFormat, nScanlineStride,
1931 pFirstScanline, pMem, pPal,
1932 bitsPerPixel[nScanlineFormat], rDamage );
1934 case Format::ONE_BIT_LSB_PAL:
1935 return createRenderer<PixelFormatTraits_PAL1_LSB,StdMasks>(
1936 aBounds, nScanlineFormat, nScanlineStride,
1937 pFirstScanline, pMem, pPal,
1938 bitsPerPixel[nScanlineFormat], rDamage );
1941 // ----------------------------------------------------------------------
1942 // four bit formats
1944 case Format::FOUR_BIT_MSB_GREY:
1945 return createRenderer<PixelFormatTraits_GREY4_MSB,StdMasks>(
1946 aBounds, nScanlineFormat, nScanlineStride,
1947 pFirstScanline, pMem, pPal, rDamage );
1949 case Format::FOUR_BIT_LSB_GREY:
1950 return createRenderer<PixelFormatTraits_GREY4_LSB,StdMasks>(
1951 aBounds, nScanlineFormat, nScanlineStride,
1952 pFirstScanline, pMem, pPal, rDamage );
1954 case Format::FOUR_BIT_MSB_PAL:
1955 return createRenderer<PixelFormatTraits_PAL4_MSB,StdMasks>(
1956 aBounds, nScanlineFormat, nScanlineStride,
1957 pFirstScanline, pMem, pPal,
1958 bitsPerPixel[nScanlineFormat], rDamage );
1960 case Format::FOUR_BIT_LSB_PAL:
1961 return createRenderer<PixelFormatTraits_PAL4_LSB,StdMasks>(
1962 aBounds, nScanlineFormat, nScanlineStride,
1963 pFirstScanline, pMem, pPal,
1964 bitsPerPixel[nScanlineFormat], rDamage );
1967 // ----------------------------------------------------------------------
1968 // eight bit formats
1970 case Format::EIGHT_BIT_GREY:
1971 return createRenderer<PixelFormatTraits_GREY8,StdMasks>(
1972 aBounds, nScanlineFormat, nScanlineStride,
1973 pFirstScanline, pMem, pPal, rDamage );
1975 case Format::EIGHT_BIT_PAL:
1976 return createRenderer<PixelFormatTraits_PAL8,StdMasks>(
1977 aBounds, nScanlineFormat, nScanlineStride,
1978 pFirstScanline, pMem, pPal,
1979 bitsPerPixel[nScanlineFormat], rDamage );
1982 // ----------------------------------------------------------------------
1983 // sixteen bit formats
1985 case Format::SIXTEEN_BIT_LSB_TC_MASK:
1986 return createRenderer<PixelFormatTraits_RGB16_565_LSB,StdMasks>(
1987 aBounds, nScanlineFormat, nScanlineStride,
1988 pFirstScanline, pMem, pPal, rDamage );
1990 case Format::SIXTEEN_BIT_MSB_TC_MASK:
1991 return createRenderer<PixelFormatTraits_RGB16_565_MSB,StdMasks>(
1992 aBounds, nScanlineFormat, nScanlineStride,
1993 pFirstScanline, pMem, pPal, rDamage );
1996 // ----------------------------------------------------------------------
1997 // twentyfour bit formats
1998 case Format::TWENTYFOUR_BIT_TC_MASK:
1999 return createRenderer<PixelFormatTraits_BGR24,StdMasks>(
2000 aBounds, nScanlineFormat, nScanlineStride,
2001 pFirstScanline, pMem, pPal, rDamage );
2004 // ----------------------------------------------------------------------
2005 // thirtytwo bit formats
2007 case Format::THIRTYTWO_BIT_TC_MASK:
2008 return createRenderer<PixelFormatTraits_RGB32_888,StdMasks>(
2009 aBounds, nScanlineFormat, nScanlineStride,
2010 pFirstScanline, pMem, pPal, rDamage );
2012 case Format::THIRTYTWO_BIT_TC_MASK_ARGB:
2013 return createRenderer<PixelFormatTraits_BGR32_888,StdMasks>(
2014 aBounds, nScanlineFormat, nScanlineStride,
2015 pFirstScanline, pMem, pPal, rDamage );
2018 // TODO(F3): other formats not yet implemented
2019 return BitmapDeviceSharedPtr();
2021 } // namespace
2024 BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
2025 bool bTopDown,
2026 sal_Int32 nScanlineFormat )
2028 return createBitmapDeviceImpl( rSize,
2029 bTopDown,
2030 nScanlineFormat,
2031 boost::shared_array< sal_uInt8 >(),
2032 PaletteMemorySharedVector(),
2033 NULL,
2034 IBitmapDeviceDamageTrackerSharedPtr() );
2037 BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
2038 bool bTopDown,
2039 sal_Int32 nScanlineFormat,
2040 const PaletteMemorySharedVector& rPalette )
2042 return createBitmapDeviceImpl( rSize,
2043 bTopDown,
2044 nScanlineFormat,
2045 boost::shared_array< sal_uInt8 >(),
2046 rPalette,
2047 NULL,
2048 IBitmapDeviceDamageTrackerSharedPtr() );
2051 BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
2052 bool bTopDown,
2053 sal_Int32 nScanlineFormat,
2054 const RawMemorySharedArray& rMem,
2055 const PaletteMemorySharedVector& rPalette )
2057 return createBitmapDeviceImpl( rSize,
2058 bTopDown,
2059 nScanlineFormat,
2060 rMem,
2061 rPalette,
2062 NULL,
2063 IBitmapDeviceDamageTrackerSharedPtr() );
2066 BitmapDeviceSharedPtr subsetBitmapDevice( const BitmapDeviceSharedPtr& rProto,
2067 const basegfx::B2IBox& rSubset )
2069 return createBitmapDeviceImpl( rProto->getSize(),
2070 rProto->isTopDown(),
2071 rProto->getScanlineFormat(),
2072 rProto->getBuffer(),
2073 rProto->getPalette(),
2074 &rSubset,
2075 rProto->getDamageTracker() );
2078 BitmapDeviceSharedPtr cloneBitmapDevice( const basegfx::B2IVector& rSize,
2079 const BitmapDeviceSharedPtr& rProto )
2081 return createBitmapDeviceImpl( rSize,
2082 rProto->isTopDown(),
2083 rProto->getScanlineFormat(),
2084 boost::shared_array< sal_uInt8 >(),
2085 rProto->getPalette(),
2086 NULL,
2087 rProto->getDamageTracker() );
2090 //----------------------------------------------------------------------------------
2092 /// Clone our device, with GenericImageAccessor to handle all formats
2093 BitmapDeviceSharedPtr BitmapDevice::getGenericRenderer() const
2095 return mpImpl->mpGenericRenderer;
2098 } // namespace basebmp
2100 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */