merge the formfield patch from ooo-build
[ooovba.git] / basebmp / source / bitmapdevice.cxx
blobd9e51a9063eb5ee39d2f4a4ff2c1933af84cb69f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bitmapdevice.cxx,v $
10 * $Revision: 1.33.4.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // FIXME: in vigra
32 #if defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x580)
33 #include <math.h> // needed for fabs, hypot
34 #endif
35 #include "basebmp/bitmapdevice.hxx"
37 #include "basebmp/compositeiterator.hxx"
38 #include "basebmp/iteratortraits.hxx"
40 #include "basebmp/accessor.hxx"
41 #include "basebmp/accessortraits.hxx"
42 #include "basebmp/accessoradapters.hxx"
43 #include "basebmp/colorblendaccessoradapter.hxx"
45 #include "basebmp/color.hxx"
46 #include "basebmp/colormisc.hxx"
47 #include "basebmp/colortraits.hxx"
49 #include "basebmp/greylevelformats.hxx"
50 #include "basebmp/paletteformats.hxx"
51 #include "basebmp/rgbmaskpixelformats.hxx"
52 #include "basebmp/rgb24pixelformats.hxx"
54 #include "basebmp/scanlineformats.hxx"
55 #include "basebmp/fillimage.hxx"
56 #include "basebmp/scaleimage.hxx"
57 #include "basebmp/clippedlinerenderer.hxx"
58 #include "basebmp/polypolygonrenderer.hxx"
59 #include "basebmp/genericcolorimageaccessor.hxx"
61 #include "basebmp/tools.hxx"
62 #include "intconversion.hxx"
64 #include <rtl/alloc.h>
65 #include <rtl/memory.h>
66 #include <osl/diagnose.h>
68 #include <basegfx/tools/tools.hxx>
69 #include <basegfx/range/b2irange.hxx>
70 #include <basegfx/range/b2drange.hxx>
71 #include <basegfx/polygon/b2dpolygon.hxx>
72 #include <basegfx/polygon/b2dpolygontools.hxx>
73 #include <basegfx/polygon/b2dpolypolygontools.hxx>
74 #include <basegfx/point/b2ipoint.hxx>
75 #include <basegfx/vector/b2ivector.hxx>
77 #include <vigra/iteratortraits.hxx>
78 #include <vigra/rgbvalue.hxx>
79 #include <vigra/copyimage.hxx>
80 #include <vigra/tuple.hxx>
83 namespace vigra
86 /// componentwise xor of an RGBValue (missing from rgbvalue.hxx)
87 template< class Value, unsigned int RedIndex, unsigned int BlueIndex, unsigned int GreenIndex >
88 inline RGBValue<Value, RedIndex, GreenIndex, BlueIndex>
89 operator^( RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& lhs,
90 RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& rhs )
92 RGBValue<Value, RedIndex, GreenIndex, BlueIndex> res(
93 lhs[0] ^ rhs[0],
94 lhs[1] ^ rhs[1],
95 lhs[2] ^ rhs[2]);
96 return res;
100 namespace basebmp
103 namespace
105 /** Create the type for an accessor that takes the (mask,bitmap)
106 input value generated from a JoinImageAccessorAdapter, and
107 pipe that through a mask functor.
109 @tpl DestAccessor
110 Destination bitmap accessor
112 @tpl JoinedAccessor
113 Input accessor, is expected to generate a std::pair as the
114 value type
116 @tpl MaskFunctorMode
117 Either FastMask or NoFastMask, depending on whether the mask
118 is guaranteed to contain only 0s and 1s.
120 template< class DestAccessor,
121 class JoinedAccessor,
122 bool polarity,
123 typename MaskFunctorMode > struct masked_input_splitting_accessor
125 typedef BinarySetterFunctionAccessorAdapter<
126 DestAccessor,
127 BinaryFunctorSplittingWrapper<
128 typename outputMaskFunctorSelector<
129 typename JoinedAccessor::value_type::first_type,
130 typename JoinedAccessor::value_type::second_type,
131 polarity,
132 MaskFunctorMode >::type > > type;
137 // Actual BitmapDevice implementation (templatized by accessor and iterator)
138 //--------------------------------------------------------------------------
140 /** Implementation of the BitmapDevice interface
142 @tpl DestIterator
143 Iterator to access bitmap memory
145 @tpl RawAccessor
146 Raw accessor, to access pixel values directly
148 @tpl AccessorSelector
149 Accessor adapter selector, which, when applying the nested
150 template metafunction wrap_accessor to one of the raw bitmap
151 accessors, yields a member type named 'type', which is a
152 wrapped accessor that map color values.
154 @tpl Masks
155 Traits template, containing nested traits
156 clipmask_format_traits and alphamask_format_traits, which
157 determine what specialized formats are to be used for clip and
158 alpha masks. With those mask formats, clipping and alpha
159 blending is handled natively.
161 template< class DestIterator,
162 class RawAccessor,
163 class AccessorSelector,
164 class Masks > class BitmapRenderer :
165 public BitmapDevice
167 public:
168 typedef DestIterator dest_iterator_type;
169 typedef RawAccessor raw_accessor_type;
170 typedef AccessorSelector accessor_selector;
172 typedef typename Masks::clipmask_format_traits::iterator_type mask_iterator_type;
173 typedef typename Masks::clipmask_format_traits::raw_accessor_type mask_rawaccessor_type;
174 typedef typename Masks::clipmask_format_traits::accessor_selector mask_accessorselector_type;
176 typedef typename Masks::alphamask_format_traits::iterator_type alphamask_iterator_type;
177 typedef typename Masks::alphamask_format_traits::raw_accessor_type alphamask_rawaccessor_type;
178 typedef typename Masks::alphamask_format_traits::accessor_selector alphamask_accessorselector_type;
180 typedef typename AccessorSelector::template wrap_accessor<
181 raw_accessor_type >::type dest_accessor_type;
183 typedef AccessorTraits< dest_accessor_type > accessor_traits;
184 typedef CompositeIterator2D< dest_iterator_type,
185 mask_iterator_type > composite_iterator_type;
186 typedef CompositeIterator2D< vigra::Diff2D,
187 vigra::Diff2D > generic_composite_iterator_type;
189 typedef BitmapRenderer<mask_iterator_type,
190 mask_rawaccessor_type,
191 mask_accessorselector_type,
192 Masks> mask_bitmap_type;
193 typedef BitmapRenderer<alphamask_iterator_type,
194 alphamask_rawaccessor_type,
195 alphamask_accessorselector_type,
196 Masks> alphamask_bitmap_type;
198 // -------------------------------------------------------
200 typedef AccessorTraits< raw_accessor_type > raw_accessor_traits;
201 typedef typename uInt32Converter<
202 typename raw_accessor_type::value_type>::to to_uint32_functor;
204 // -------------------------------------------------------
206 typedef typename raw_accessor_traits::xor_accessor raw_xor_accessor_type;
207 typedef AccessorTraits<raw_xor_accessor_type> raw_xor_accessor_traits;
208 typedef typename accessor_selector::template wrap_accessor<
209 raw_xor_accessor_type >::type xor_accessor_type;
210 typedef AccessorTraits<xor_accessor_type> xor_accessor_traits;
212 // -------------------------------------------------------
214 typedef typename raw_accessor_traits::template masked_accessor<
215 mask_rawaccessor_type,
216 dest_iterator_type,
217 mask_iterator_type,
218 Masks::clipmask_polarity>::type raw_maskedaccessor_type;
219 typedef typename accessor_selector::template wrap_accessor<
220 raw_maskedaccessor_type >::type masked_accessor_type;
221 typedef typename AccessorTraits<
222 raw_maskedaccessor_type>::xor_accessor raw_maskedxor_accessor_type;
223 typedef typename accessor_selector::template wrap_accessor<
224 raw_maskedxor_accessor_type >::type masked_xoraccessor_type;
226 // -------------------------------------------------------
228 // ((iter,mask),mask) special case (e.g. for clipped
229 // drawMaskedColor())
230 typedef AccessorTraits< raw_maskedaccessor_type > raw_maskedaccessor_traits;
231 typedef typename raw_maskedaccessor_traits::template masked_accessor<
232 mask_rawaccessor_type,
233 composite_iterator_type,
234 mask_iterator_type,
235 Masks::clipmask_polarity>::type raw_maskedmask_accessor_type;
237 typedef CompositeIterator2D<
238 composite_iterator_type,
239 mask_iterator_type> composite_composite_mask_iterator_type;
241 // -------------------------------------------------------
243 typedef ConstantColorBlendSetterAccessorAdapter<
244 dest_accessor_type,
245 typename alphamask_rawaccessor_type::value_type,
246 Masks::alphamask_polarity> colorblend_accessor_type;
247 typedef AccessorTraits<colorblend_accessor_type> colorblend_accessor_traits;
248 typedef typename colorblend_accessor_traits::template masked_accessor<
249 mask_rawaccessor_type,
250 dest_iterator_type,
251 mask_iterator_type,
252 Masks::clipmask_polarity>::type masked_colorblend_accessor_type;
254 // -------------------------------------------------------
256 typedef ConstantColorBlendSetterAccessorAdapter<
257 dest_accessor_type,
258 Color,
259 Masks::alphamask_polarity> colorblend_generic_accessor_type;
260 typedef AccessorTraits<colorblend_generic_accessor_type> colorblend_generic_accessor_traits;
261 typedef typename colorblend_generic_accessor_traits::template masked_accessor<
262 mask_rawaccessor_type,
263 dest_iterator_type,
264 mask_iterator_type,
265 Masks::clipmask_polarity>::type masked_colorblend_generic_accessor_type;
267 // -------------------------------------------------------
269 typedef JoinImageAccessorAdapter< dest_accessor_type,
270 mask_rawaccessor_type > joined_image_accessor_type;
271 typedef JoinImageAccessorAdapter< GenericColorImageAccessor,
272 GenericColorImageAccessor > joined_generic_image_accessor_type;
274 // -------------------------------------------------------
276 dest_iterator_type maBegin;
277 typename accessor_traits::color_lookup maColorLookup;
278 to_uint32_functor maToUInt32Converter;
279 dest_accessor_type maAccessor;
280 colorblend_accessor_type maColorBlendAccessor;
281 colorblend_generic_accessor_type maGenericColorBlendAccessor;
282 raw_accessor_type maRawAccessor;
283 xor_accessor_type maXorAccessor;
284 raw_xor_accessor_type maRawXorAccessor;
285 masked_accessor_type maMaskedAccessor;
286 masked_colorblend_accessor_type maMaskedColorBlendAccessor;
287 masked_colorblend_generic_accessor_type maGenericMaskedColorBlendAccessor;
288 masked_xoraccessor_type maMaskedXorAccessor;
289 raw_maskedaccessor_type maRawMaskedAccessor;
290 raw_maskedxor_accessor_type maRawMaskedXorAccessor;
291 raw_maskedmask_accessor_type maRawMaskedMaskAccessor;
293 // -------------------------------------------------------
295 BitmapRenderer( const basegfx::B2IRange& rBounds,
296 sal_Int32 nScanlineFormat,
297 sal_Int32 nScanlineStride,
298 sal_uInt8* pFirstScanline,
299 dest_iterator_type begin,
300 raw_accessor_type rawAccessor,
301 dest_accessor_type accessor,
302 const RawMemorySharedArray& rMem,
303 const PaletteMemorySharedVector& rPalette ) :
304 BitmapDevice( rBounds, nScanlineFormat,
305 nScanlineStride, pFirstScanline, rMem, rPalette ),
306 maBegin( begin ),
307 maColorLookup(),
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:
325 boost::shared_ptr<BitmapRenderer> getCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
327 return boost::dynamic_pointer_cast< BitmapRenderer >( bmp );
330 virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
332 // TODO(P1): dynamic_cast usually called twice for
333 // compatible formats
334 return getCompatibleBitmap(bmp).get() != NULL;
337 boost::shared_ptr<mask_bitmap_type> getCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const
339 boost::shared_ptr<mask_bitmap_type> pMask( boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ));
341 if( !pMask )
342 return pMask;
344 if( pMask->getSize() != getSize() )
345 pMask.reset();
347 return pMask;
350 virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const
352 // TODO(P1): dynamic_cast usually called twice for
353 // compatible formats
354 return boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ).get() != NULL;
357 boost::shared_ptr<alphamask_bitmap_type> getCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
359 return boost::dynamic_pointer_cast<alphamask_bitmap_type>( bmp );
362 virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
364 // TODO(P1): dynamic_cast usually called twice for
365 // compatible formats
366 return getCompatibleAlphaMask( bmp ).get() != NULL;
369 virtual void clear_i( Color fillColor,
370 const basegfx::B2IRange& rBounds )
372 fillImage(destIterRange(maBegin,
373 maRawAccessor,
374 rBounds),
375 maColorLookup(
376 maAccessor,
377 fillColor) );
380 virtual void setPixel_i( const basegfx::B2IPoint& rPt,
381 Color pixelColor,
382 DrawMode drawMode )
384 const DestIterator pixel( maBegin +
385 vigra::Diff2D(rPt.getX(),
386 rPt.getY()) );
387 if( drawMode == DrawMode_XOR )
388 maXorAccessor.set( pixelColor,
389 pixel );
390 else
391 maAccessor.set( pixelColor,
392 pixel );
395 virtual void setPixel_i( const basegfx::B2IPoint& rPt,
396 Color pixelColor,
397 DrawMode drawMode,
398 const BitmapDeviceSharedPtr& rClip )
400 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
401 OSL_ASSERT( pMask );
403 const vigra::Diff2D offset(rPt.getX(),
404 rPt.getY());
406 const composite_iterator_type aIter(
407 maBegin + offset,
408 pMask->maBegin + offset );
410 if( drawMode == DrawMode_XOR )
411 maMaskedXorAccessor.set( pixelColor,
412 aIter );
413 else
414 maMaskedAccessor.set( pixelColor,
415 aIter );
418 virtual Color getPixel_i(const basegfx::B2IPoint& rPt )
420 const DestIterator pixel( maBegin +
421 vigra::Diff2D(rPt.getX(),
422 rPt.getY()) );
423 return maAccessor(pixel);
426 virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt )
428 const DestIterator pixel( maBegin +
429 vigra::Diff2D(rPt.getX(),
430 rPt.getY()) );
431 return maToUInt32Converter(maRawAccessor(pixel));
434 template< typename Iterator, typename Col, typename RawAcc >
435 void implRenderLine2( const basegfx::B2IPoint& rPt1,
436 const basegfx::B2IPoint& rPt2,
437 const basegfx::B2IRange& rBounds,
438 Col col,
439 const Iterator& begin,
440 const RawAcc& rawAcc )
442 renderClippedLine( rPt1,
443 rPt2,
444 rBounds,
445 col,
446 begin,
447 rawAcc );
450 template< typename Iterator, typename Accessor, typename RawAcc >
451 void implRenderLine( const basegfx::B2IPoint& rPt1,
452 const basegfx::B2IPoint& rPt2,
453 const basegfx::B2IRange& rBounds,
454 Color col,
455 const Iterator& begin,
456 const Accessor& acc,
457 const RawAcc& rawAcc )
459 implRenderLine2( rPt1,rPt2,rBounds,
460 maColorLookup( acc,
461 col ),
462 begin,
463 rawAcc );
466 template< typename Iterator, typename RawAcc, typename XorAcc >
467 void implDrawLine( const basegfx::B2IPoint& rPt1,
468 const basegfx::B2IPoint& rPt2,
469 const basegfx::B2IRange& rBounds,
470 Color col,
471 const Iterator& begin,
472 const RawAcc& rawAcc,
473 const XorAcc& xorAcc,
474 DrawMode drawMode )
476 if( drawMode == DrawMode_XOR )
477 implRenderLine( rPt1, rPt2, rBounds, col,
478 begin, maAccessor, xorAcc );
479 else
480 implRenderLine( rPt1, rPt2, rBounds, col,
481 begin, maAccessor, rawAcc );
484 virtual void drawLine_i(const basegfx::B2IPoint& rPt1,
485 const basegfx::B2IPoint& rPt2,
486 const basegfx::B2IRange& rBounds,
487 Color lineColor,
488 DrawMode drawMode )
490 implDrawLine(rPt1,rPt2,rBounds,lineColor,
491 maBegin,
492 maRawAccessor,maRawXorAccessor,drawMode);
495 composite_iterator_type getMaskedIter( const BitmapDeviceSharedPtr& rClip ) const
497 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
498 OSL_ASSERT( pMask );
500 return composite_iterator_type( maBegin,
501 pMask->maBegin );
504 virtual void drawLine_i(const basegfx::B2IPoint& rPt1,
505 const basegfx::B2IPoint& rPt2,
506 const basegfx::B2IRange& rBounds,
507 Color lineColor,
508 DrawMode drawMode,
509 const BitmapDeviceSharedPtr& rClip )
511 implDrawLine(rPt1,rPt2,rBounds,lineColor,
512 getMaskedIter(rClip),
513 maRawMaskedAccessor,
514 maRawMaskedXorAccessor,drawMode);
517 template< typename Iterator, typename RawAcc >
518 void implDrawPolygon( const basegfx::B2DPolygon& rPoly,
519 const basegfx::B2IRange& rBounds,
520 Color col,
521 const Iterator& begin,
522 const RawAcc& acc )
524 basegfx::B2DPolygon aPoly( rPoly );
525 if( rPoly.areControlPointsUsed() )
526 aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
528 const typename dest_iterator_type::value_type colorIndex( maColorLookup(
529 maAccessor,
530 col));
531 const sal_uInt32 nVertices( aPoly.count() );
532 for( sal_uInt32 i=1; i<nVertices; ++i )
533 implRenderLine2( basegfx::fround(aPoly.getB2DPoint(i-1)),
534 basegfx::fround(aPoly.getB2DPoint(i)),
535 rBounds,
536 colorIndex,
537 begin,
538 acc );
540 if( nVertices > 1 && aPoly.isClosed() )
541 implRenderLine2( basegfx::fround(aPoly.getB2DPoint(nVertices-1)),
542 basegfx::fround(aPoly.getB2DPoint(0)),
543 rBounds,
544 colorIndex,
545 begin,
546 acc );
549 virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
550 const basegfx::B2IRange& rBounds,
551 Color lineColor,
552 DrawMode drawMode )
554 if( drawMode == DrawMode_XOR )
555 implDrawPolygon( rPoly, rBounds, lineColor,
556 maBegin,
557 maRawXorAccessor );
558 else
559 implDrawPolygon( rPoly, rBounds, lineColor,
560 maBegin,
561 maRawAccessor );
564 virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
565 const basegfx::B2IRange& rBounds,
566 Color lineColor,
567 DrawMode drawMode,
568 const BitmapDeviceSharedPtr& rClip )
570 if( drawMode == DrawMode_XOR )
571 implDrawPolygon( rPoly, rBounds, lineColor,
572 getMaskedIter(rClip),
573 maRawMaskedXorAccessor );
574 else
575 implDrawPolygon( rPoly, rBounds, lineColor,
576 getMaskedIter(rClip),
577 maRawMaskedAccessor );
580 template< typename Iterator, typename RawAcc >
581 void implFillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
582 Color col,
583 const Iterator& begin,
584 const RawAcc& acc,
585 const basegfx::B2IRange& rBounds )
587 basegfx::B2DPolyPolygon aPoly( rPoly );
588 if( rPoly.areControlPointsUsed() )
589 aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
591 renderClippedPolyPolygon( begin,
592 acc,
593 maColorLookup( maAccessor,
594 col),
595 rBounds,
596 aPoly,
597 basegfx::FillRule_EVEN_ODD );
600 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
601 Color fillColor,
602 DrawMode drawMode,
603 const basegfx::B2IRange& rBounds )
605 if( drawMode == DrawMode_XOR )
606 implFillPolyPolygon( rPoly, fillColor,
607 maBegin,
608 maRawXorAccessor,
609 rBounds );
610 else
611 implFillPolyPolygon( rPoly, fillColor,
612 maBegin,
613 maRawAccessor,
614 rBounds );
617 virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
618 Color fillColor,
619 DrawMode drawMode,
620 const basegfx::B2IRange& rBounds,
621 const BitmapDeviceSharedPtr& rClip )
623 if( drawMode == DrawMode_XOR )
624 implFillPolyPolygon( rPoly, fillColor,
625 getMaskedIter(rClip),
626 maRawMaskedXorAccessor,
627 rBounds );
628 else
629 implFillPolyPolygon( rPoly, fillColor,
630 getMaskedIter(rClip),
631 maRawMaskedAccessor,
632 rBounds );
635 template< typename Iterator, typename RawAcc >
636 void implDrawBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
637 const basegfx::B2IRange& rSrcRect,
638 const basegfx::B2IRange& rDstRect,
639 const Iterator& begin,
640 const RawAcc& acc)
642 boost::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
643 OSL_ASSERT( pSrcBmp );
645 scaleImage(
646 srcIterRange(pSrcBmp->maBegin,
647 pSrcBmp->maRawAccessor,
648 rSrcRect),
649 destIterRange(begin,
650 acc,
651 rDstRect),
652 rSrcBitmap.get() == this );
655 template< typename Iterator, typename Acc >
656 void implDrawBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
657 const basegfx::B2IRange& rSrcRect,
658 const basegfx::B2IRange& rDstRect,
659 const Iterator& begin,
660 const Acc& acc)
662 GenericColorImageAccessor aSrcAcc( rSrcBitmap );
664 scaleImage(
665 srcIterRange(vigra::Diff2D(),
666 aSrcAcc,
667 rSrcRect),
668 destIterRange(begin,
669 acc,
670 rDstRect));
673 virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
674 const basegfx::B2IRange& rSrcRect,
675 const basegfx::B2IRange& rDstRect,
676 DrawMode drawMode )
678 if( isCompatibleBitmap( rSrcBitmap ) )
680 if( drawMode == DrawMode_XOR )
681 implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
682 maBegin,
683 maRawXorAccessor);
684 else
685 implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
686 maBegin,
687 maRawAccessor);
689 else
691 if( drawMode == DrawMode_XOR )
692 implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
693 maBegin,
694 maXorAccessor);
695 else
696 implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
697 maBegin,
698 maAccessor);
702 virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
703 const basegfx::B2IRange& rSrcRect,
704 const basegfx::B2IRange& rDstRect,
705 DrawMode drawMode,
706 const BitmapDeviceSharedPtr& rClip )
708 if( isCompatibleBitmap( rSrcBitmap ) )
710 if( drawMode == DrawMode_XOR )
711 implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
712 getMaskedIter(rClip),
713 maRawMaskedXorAccessor);
714 else
715 implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
716 getMaskedIter(rClip),
717 maRawMaskedAccessor);
719 else
721 if( drawMode == DrawMode_XOR )
722 implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
723 getMaskedIter(rClip),
724 maMaskedXorAccessor);
725 else
726 implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
727 getMaskedIter(rClip),
728 maMaskedAccessor);
732 virtual void drawMaskedColor_i(Color aSrcColor,
733 const BitmapDeviceSharedPtr& rAlphaMask,
734 const basegfx::B2IRange& rSrcRect,
735 const basegfx::B2IPoint& rDstPoint )
737 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rAlphaMask) );
738 boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
740 if( pAlpha )
742 maColorBlendAccessor.setColor( aSrcColor );
744 vigra::copyImage( srcIterRange(pAlpha->maBegin,
745 pAlpha->maRawAccessor,
746 rSrcRect),
747 destIter(maBegin,
748 maColorBlendAccessor,
749 rDstPoint) );
751 else if( pMask )
753 const composite_iterator_type aBegin(
754 maBegin + vigra::Diff2D(rDstPoint.getX(),
755 rDstPoint.getY()),
756 pMask->maBegin + topLeft(rSrcRect) );
758 fillImage(aBegin,
759 aBegin + vigra::Diff2D(rSrcRect.getWidth(),
760 rSrcRect.getHeight()),
761 maRawMaskedAccessor,
762 maColorLookup(
763 maAccessor,
764 aSrcColor) );
766 else
768 GenericColorImageAccessor aSrcAcc( rAlphaMask );
769 maGenericColorBlendAccessor.setColor( aSrcColor );
771 vigra::copyImage( srcIterRange(vigra::Diff2D(),
772 aSrcAcc,
773 rSrcRect),
774 destIter(maBegin,
775 maGenericColorBlendAccessor,
776 rDstPoint) );
780 virtual void drawMaskedColor_i(Color aSrcColor,
781 const BitmapDeviceSharedPtr& rAlphaMask,
782 const basegfx::B2IRange& rSrcRect,
783 const basegfx::B2IPoint& rDstPoint,
784 const BitmapDeviceSharedPtr& rClip )
786 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rAlphaMask) );
787 boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
789 if( pAlpha )
791 const composite_iterator_type aBegin( getMaskedIter(rClip) );
792 maMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
793 aSrcColor );
795 vigra::copyImage( srcIterRange(pAlpha->maBegin,
796 pAlpha->maRawAccessor,
797 rSrcRect),
798 destIter(aBegin,
799 maMaskedColorBlendAccessor,
800 rDstPoint) );
802 else if( pMask )
804 boost::shared_ptr<mask_bitmap_type> pClipMask( getCompatibleClipMask(rClip) );
805 OSL_ASSERT( pClipMask );
807 // setup a ((iter,mask),clipMask) composite composite
808 // iterator, to pass both masks (clip and alpha mask)
809 // to the algorithm
810 const composite_composite_mask_iterator_type aBegin(
811 composite_iterator_type(
812 maBegin + vigra::Diff2D(rDstPoint.getX(),
813 rDstPoint.getY()),
814 pMask->maBegin + topLeft(rSrcRect)),
815 pClipMask->maBegin + vigra::Diff2D(rDstPoint.getX(),
816 rDstPoint.getY()) );
818 fillImage(aBegin,
819 aBegin + vigra::Diff2D(rSrcRect.getWidth(),
820 rSrcRect.getHeight()),
821 maRawMaskedMaskAccessor,
822 maColorLookup(
823 maAccessor,
824 aSrcColor) );
826 else
828 GenericColorImageAccessor aSrcAcc( rAlphaMask );
829 const composite_iterator_type aBegin( getMaskedIter(rClip) );
830 maGenericMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
831 aSrcColor );
833 vigra::copyImage( srcIterRange(vigra::Diff2D(),
834 aSrcAcc,
835 rSrcRect),
836 destIter(aBegin,
837 maGenericMaskedColorBlendAccessor,
838 rDstPoint) );
842 template< typename Iterator, typename Acc >
843 void implDrawMaskedBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
844 const BitmapDeviceSharedPtr& rMask,
845 const basegfx::B2IRange& rSrcRect,
846 const basegfx::B2IRange& rDstRect,
847 const Iterator& begin,
848 const Acc& acc)
850 boost::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
851 boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rMask) );
852 OSL_ASSERT( pMask && pSrcBmp );
854 scaleImage(
855 srcIterRange(composite_iterator_type(
856 pSrcBmp->maBegin,
857 pMask->maBegin),
858 joined_image_accessor_type(
859 pSrcBmp->maAccessor,
860 pMask->maRawAccessor),
861 rSrcRect),
862 destIterRange(begin,
863 typename masked_input_splitting_accessor<
864 Acc,
865 joined_image_accessor_type,
866 Masks::clipmask_polarity,
867 FastMask >::type(acc),
868 rDstRect),
869 rSrcBitmap.get() == this);
872 template< typename Iterator, typename Acc >
873 void implDrawMaskedBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
874 const BitmapDeviceSharedPtr& rMask,
875 const basegfx::B2IRange& rSrcRect,
876 const basegfx::B2IRange& rDstRect,
877 const Iterator& begin,
878 const Acc& acc)
880 GenericColorImageAccessor aSrcAcc( rSrcBitmap );
881 GenericColorImageAccessor aMaskAcc( rMask );
883 const vigra::Diff2D aTopLeft(rSrcRect.getMinX(),
884 rSrcRect.getMinY());
885 const vigra::Diff2D aBottomRight(rSrcRect.getMaxX(),
886 rSrcRect.getMaxY());
887 scaleImage(
888 vigra::make_triple(
889 generic_composite_iterator_type(
890 aTopLeft,aTopLeft),
891 generic_composite_iterator_type(
892 aBottomRight,aBottomRight),
893 joined_generic_image_accessor_type(
894 aSrcAcc,
895 aMaskAcc)),
896 destIterRange(begin,
897 typename masked_input_splitting_accessor<
898 Acc,
899 joined_generic_image_accessor_type,
900 Masks::clipmask_polarity,
901 NoFastMask >::type(acc),
902 rDstRect));
905 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
906 const BitmapDeviceSharedPtr& rMask,
907 const basegfx::B2IRange& rSrcRect,
908 const basegfx::B2IRange& rDstRect,
909 DrawMode drawMode )
911 if( isCompatibleClipMask(rMask) &&
912 isCompatibleBitmap(rSrcBitmap) )
914 if( drawMode == DrawMode_XOR )
915 implDrawMaskedBitmap(rSrcBitmap, rMask,
916 rSrcRect, rDstRect,
917 maBegin,
918 maXorAccessor);
919 else
920 implDrawMaskedBitmap(rSrcBitmap, rMask,
921 rSrcRect, rDstRect,
922 maBegin,
923 maAccessor);
925 else
927 if( drawMode == DrawMode_XOR )
928 implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
929 rSrcRect, rDstRect,
930 maBegin,
931 maXorAccessor);
932 else
933 implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
934 rSrcRect, rDstRect,
935 maBegin,
936 maAccessor);
940 virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
941 const BitmapDeviceSharedPtr& rMask,
942 const basegfx::B2IRange& rSrcRect,
943 const basegfx::B2IRange& rDstRect,
944 DrawMode drawMode,
945 const BitmapDeviceSharedPtr& rClip )
947 if( isCompatibleClipMask(rMask) &&
948 isCompatibleBitmap(rSrcBitmap) )
950 if( drawMode == DrawMode_XOR )
951 implDrawMaskedBitmap(rSrcBitmap, rMask,
952 rSrcRect, rDstRect,
953 getMaskedIter(rClip),
954 maMaskedXorAccessor);
955 else
956 implDrawMaskedBitmap(rSrcBitmap, rMask,
957 rSrcRect, rDstRect,
958 getMaskedIter(rClip),
959 maMaskedAccessor);
961 else
963 if( drawMode == DrawMode_XOR )
964 implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
965 rSrcRect, rDstRect,
966 getMaskedIter(rClip),
967 maMaskedXorAccessor);
968 else
969 implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
970 rSrcRect, rDstRect,
971 getMaskedIter(rClip),
972 maMaskedAccessor);
976 } // namespace
978 struct ImplBitmapDevice
980 /** Bitmap memory plus deleter.
982 Always points to the start of the mem
984 RawMemorySharedArray mpMem;
986 /// Palette memory plus deleter (might be NULL)
987 PaletteMemorySharedVector mpPalette;
989 /** Bounds of the device.
991 maBounds.getWidth()/getHeight() yield the true size of the
992 device (i.e. the rectangle given by maBounds covers the device
993 area under the excluding-bottommost-and-rightmost-pixels fill
994 rule)
996 basegfx::B2IRange maBounds;
998 /** Bounds of the device.
1000 maBounds.getWidth()/getHeight() yield the true size of the
1001 device minus 1 (i.e. the rectangle given by maBounds covers
1002 the device area under the
1003 including-the-bottommost-and-rightmost-pixels fill rule).
1005 The member is used to clip line stroking against the device
1006 bounds.
1008 basegfx::B2IRange maLineClipRect;
1010 /// Scanline format, as provided at the constructor
1011 sal_Int32 mnScanlineFormat;
1013 /// Scanline stride. Negative for bottom-to-top formats
1014 sal_Int32 mnScanlineStride;
1016 /// raw ptr to 0th scanline. used for cloning a generic renderer
1017 sal_uInt8* mpFirstScanline;
1019 /** (Optional) device sharing the same memory, and used for input
1020 clip masks/alpha masks/bitmaps that don't match our exact
1021 bitmap format.
1023 This is to avoid the combinatorical explosion when dealing
1024 with n bitmap formats, which could be combined with n clip
1025 masks, alpha masks and bitmap masks (yielding a total of n^4
1026 combinations). Since each BitmapRenderer is specialized for
1027 one specific combination of said formats, a lot of duplicate
1028 code would be generated, most of which probably never
1029 used. Therefore, only the most common combinations are
1030 specialized templates, the remainder gets handled by this
1031 generic renderer (via runtime polymorphism).
1033 BitmapDeviceSharedPtr mpGenericRenderer;
1037 BitmapDevice::BitmapDevice( const basegfx::B2IRange& rBounds,
1038 sal_Int32 nScanlineFormat,
1039 sal_Int32 nScanlineStride,
1040 sal_uInt8* pFirstScanline,
1041 const RawMemorySharedArray& rMem,
1042 const PaletteMemorySharedVector& rPalette ) :
1043 mpImpl( new ImplBitmapDevice )
1045 mpImpl->mpMem = rMem;
1046 mpImpl->mpPalette = rPalette;
1047 mpImpl->maBounds = rBounds;
1048 mpImpl->maLineClipRect = basegfx::B2IRange( rBounds.getMinX(),
1049 rBounds.getMinY(),
1050 rBounds.getMaxX()-1,
1051 rBounds.getMaxY()-1 );
1052 mpImpl->mnScanlineFormat = nScanlineFormat;
1053 mpImpl->mnScanlineStride = nScanlineStride;
1054 mpImpl->mpFirstScanline = pFirstScanline;
1057 BitmapDevice::~BitmapDevice()
1059 // outline, because of internal ImplBitmapDevice
1062 basegfx::B2IVector BitmapDevice::getSize() const
1065 return basegfx::B2IVector(
1066 mpImpl->maBounds.getMaxX() - mpImpl->maBounds.getMinX(),
1067 mpImpl->maBounds.getMaxY() - mpImpl->maBounds.getMinY() );
1070 bool BitmapDevice::isTopDown() const
1072 return mpImpl->mnScanlineStride >= 0;
1075 sal_Int32 BitmapDevice::getScanlineFormat() const
1077 return mpImpl->mnScanlineFormat;
1080 sal_Int32 BitmapDevice::getScanlineStride() const
1082 return mpImpl->mnScanlineStride < 0 ?
1083 -mpImpl->mnScanlineStride : mpImpl->mnScanlineStride;
1086 RawMemorySharedArray BitmapDevice::getBuffer() const
1088 return mpImpl->mpMem;
1091 PaletteMemorySharedVector BitmapDevice::getPalette() const
1093 return mpImpl->mpPalette;
1096 sal_Int32 BitmapDevice::getPaletteEntryCount() const
1098 return mpImpl->mpPalette ? mpImpl->mpPalette->size() : 0;
1101 void BitmapDevice::clear( Color fillColor )
1103 clear_i( fillColor, mpImpl->maBounds );
1106 void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
1107 Color lineColor,
1108 DrawMode drawMode )
1110 if( mpImpl->maLineClipRect.isInside(rPt) )
1111 setPixel_i(rPt,lineColor,drawMode);
1114 void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
1115 Color lineColor,
1116 DrawMode drawMode,
1117 const BitmapDeviceSharedPtr& rClip )
1119 if( !rClip )
1121 setPixel(rPt,lineColor,drawMode);
1122 return;
1125 if( mpImpl->maLineClipRect.isInside(rPt) )
1127 if( isCompatibleClipMask( rClip ) )
1128 setPixel_i(rPt,lineColor,drawMode,rClip);
1129 else
1130 getGenericRenderer()->setPixel( rPt, lineColor, drawMode, rClip );
1134 Color BitmapDevice::getPixel( const basegfx::B2IPoint& rPt )
1136 if( mpImpl->maLineClipRect.isInside(rPt) )
1137 return getPixel_i(rPt);
1139 return Color();
1142 sal_uInt32 BitmapDevice::getPixelData( const basegfx::B2IPoint& rPt )
1144 if( mpImpl->maLineClipRect.isInside(rPt) )
1145 return getPixelData_i(rPt);
1147 return 0;
1150 void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
1151 const basegfx::B2IPoint& rPt2,
1152 Color lineColor,
1153 DrawMode drawMode )
1155 drawLine_i( rPt1,
1156 rPt2,
1157 mpImpl->maLineClipRect,
1158 lineColor,
1159 drawMode );
1162 void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
1163 const basegfx::B2IPoint& rPt2,
1164 Color lineColor,
1165 DrawMode drawMode,
1166 const BitmapDeviceSharedPtr& rClip )
1168 if( !rClip )
1170 drawLine(rPt1,rPt2,lineColor,drawMode);
1171 return;
1174 if( isCompatibleClipMask( rClip ) )
1175 drawLine_i( rPt1,
1176 rPt2,
1177 mpImpl->maLineClipRect,
1178 lineColor,
1179 drawMode,
1180 rClip );
1181 else
1182 getGenericRenderer()->drawLine( rPt1, rPt2, lineColor,
1183 drawMode, rClip );
1186 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
1187 Color lineColor,
1188 DrawMode drawMode )
1190 const sal_uInt32 numVertices( rPoly.count() );
1191 if( numVertices )
1192 drawPolygon_i( rPoly,
1193 mpImpl->maLineClipRect,
1194 lineColor, drawMode );
1197 void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
1198 Color lineColor,
1199 DrawMode drawMode,
1200 const BitmapDeviceSharedPtr& rClip )
1202 if( !rClip )
1204 drawPolygon(rPoly,lineColor,drawMode);
1205 return;
1208 const sal_uInt32 numVertices( rPoly.count() );
1209 if( numVertices )
1211 if( isCompatibleClipMask( rClip ) )
1212 drawPolygon_i( rPoly,
1213 mpImpl->maLineClipRect,
1214 lineColor, drawMode, rClip );
1215 else
1216 getGenericRenderer()->drawPolygon( rPoly, lineColor,
1217 drawMode, rClip );
1221 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
1222 Color fillColor,
1223 DrawMode drawMode )
1225 fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds );
1228 void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
1229 Color fillColor,
1230 DrawMode drawMode,
1231 const BitmapDeviceSharedPtr& rClip )
1233 if( !rClip )
1235 fillPolyPolygon(rPoly,fillColor,drawMode);
1236 return;
1239 if( isCompatibleClipMask( rClip ) )
1240 fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds, rClip );
1241 else
1242 getGenericRenderer()->fillPolyPolygon( rPoly, fillColor,
1243 drawMode, rClip );
1247 namespace
1249 void assertImagePoint( const basegfx::B2IPoint& rPt,
1250 const basegfx::B2IRange& rPermittedRange )
1252 (void)rPt; (void)rPermittedRange;
1253 OSL_ASSERT( rPermittedRange.isInside(rPt) );
1256 void assertImageRange( const basegfx::B2IRange& rRange,
1257 const basegfx::B2IRange& rPermittedRange )
1259 #if OSL_DEBUG_LEVEL > 0
1260 basegfx::B2IRange aRange( rRange );
1261 aRange.intersect( rPermittedRange );
1263 OSL_ASSERT( aRange == rRange );
1264 #else
1265 (void)rRange; (void)rPermittedRange;
1266 #endif
1269 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1270 // to basegfx, and use here!
1271 bool clipAreaImpl( ::basegfx::B2IRange& io_rSourceArea,
1272 ::basegfx::B2IPoint& io_rDestPoint,
1273 const ::basegfx::B2IRange& rSourceBounds,
1274 const ::basegfx::B2IRange& rDestBounds )
1276 const ::basegfx::B2IPoint aSourceTopLeft(
1277 io_rSourceArea.getMinimum() );
1279 ::basegfx::B2IRange aLocalSourceArea( io_rSourceArea );
1281 // clip source area (which must be inside rSourceBounds)
1282 aLocalSourceArea.intersect( rSourceBounds );
1284 if( aLocalSourceArea.isEmpty() )
1285 return false;
1287 // calc relative new source area points (relative to orig
1288 // source area)
1289 const ::basegfx::B2IVector aUpperLeftOffset(
1290 aLocalSourceArea.getMinimum()-aSourceTopLeft );
1291 const ::basegfx::B2IVector aLowerRightOffset(
1292 aLocalSourceArea.getMaximum()-aSourceTopLeft );
1294 ::basegfx::B2IRange aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
1295 io_rDestPoint + aLowerRightOffset );
1297 // clip dest area (which must be inside rDestBounds)
1298 aLocalDestArea.intersect( rDestBounds );
1300 if( aLocalDestArea.isEmpty() )
1301 return false;
1303 // calc relative new dest area points (relative to orig
1304 // source area)
1305 const ::basegfx::B2IVector aDestUpperLeftOffset(
1306 aLocalDestArea.getMinimum()-io_rDestPoint );
1307 const ::basegfx::B2IVector aDestLowerRightOffset(
1308 aLocalDestArea.getMaximum()-io_rDestPoint );
1310 io_rSourceArea = ::basegfx::B2IRange( aSourceTopLeft + aDestUpperLeftOffset,
1311 aSourceTopLeft + aDestLowerRightOffset );
1312 io_rDestPoint = aLocalDestArea.getMinimum();
1314 return true;
1317 // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1318 // to basegfx, and use here!
1319 bool clipAreaImpl( ::basegfx::B2IRange& io_rDestArea,
1320 ::basegfx::B2IRange& io_rSourceArea,
1321 const ::basegfx::B2IRange& rDestBounds,
1322 const ::basegfx::B2IRange& rSourceBounds )
1324 // extract inherent scale
1325 const double nScaleX( io_rDestArea.getWidth() / (double)io_rSourceArea.getWidth() );
1326 const double nScaleY( io_rDestArea.getHeight() / (double)io_rSourceArea.getHeight() );
1328 // extract range origins
1329 const basegfx::B2IPoint aDestTopLeft(
1330 io_rDestArea.getMinimum() );
1331 const ::basegfx::B2IPoint aSourceTopLeft(
1332 io_rSourceArea.getMinimum() );
1334 ::basegfx::B2IRange aLocalSourceArea( io_rSourceArea );
1336 // clip source area (which must be inside rSourceBounds)
1337 aLocalSourceArea.intersect( rSourceBounds );
1339 if( aLocalSourceArea.isEmpty() )
1340 return false;
1342 // calc relative new source area points (relative to orig
1343 // source area)
1344 const ::basegfx::B2IVector aUpperLeftOffset(
1345 aLocalSourceArea.getMinimum()-aSourceTopLeft );
1346 const ::basegfx::B2IVector aLowerRightOffset(
1347 aLocalSourceArea.getMaximum()-aSourceTopLeft );
1349 ::basegfx::B2IRange aLocalDestArea( basegfx::fround(aDestTopLeft.getX() + nScaleX*aUpperLeftOffset.getX()),
1350 basegfx::fround(aDestTopLeft.getY() + nScaleY*aUpperLeftOffset.getY()),
1351 basegfx::fround(aDestTopLeft.getX() + nScaleX*aLowerRightOffset.getX()),
1352 basegfx::fround(aDestTopLeft.getY() + nScaleY*aLowerRightOffset.getY()) );
1354 // clip dest area (which must be inside rDestBounds)
1355 aLocalDestArea.intersect( rDestBounds );
1357 if( aLocalDestArea.isEmpty() )
1358 return false;
1360 // calc relative new dest area points (relative to orig
1361 // source area)
1362 const ::basegfx::B2IVector aDestUpperLeftOffset(
1363 aLocalDestArea.getMinimum()-aDestTopLeft );
1364 const ::basegfx::B2IVector aDestLowerRightOffset(
1365 aLocalDestArea.getMaximum()-aDestTopLeft );
1367 io_rSourceArea = ::basegfx::B2IRange( basegfx::fround(aSourceTopLeft.getX() + aDestUpperLeftOffset.getX()/nScaleX),
1368 basegfx::fround(aSourceTopLeft.getY() + aDestUpperLeftOffset.getY()/nScaleY),
1369 basegfx::fround(aSourceTopLeft.getX() + aDestLowerRightOffset.getX()/nScaleX),
1370 basegfx::fround(aSourceTopLeft.getY() + aDestLowerRightOffset.getY()/nScaleY) );
1371 io_rDestArea = aLocalDestArea;
1373 // final source area clip (chopping round-offs)
1374 io_rSourceArea.intersect( rSourceBounds );
1376 if( io_rSourceArea.isEmpty() )
1377 return false;
1380 return true;
1384 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1385 const basegfx::B2IRange& rSrcRect,
1386 const basegfx::B2IRange& rDstRect,
1387 DrawMode drawMode )
1389 const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1390 const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1391 basegfx::B2IRange aSrcRange( rSrcRect );
1392 basegfx::B2IRange aDestRange( rDstRect );
1394 if( clipAreaImpl( aDestRange,
1395 aSrcRange,
1396 mpImpl->maBounds,
1397 aSrcBounds ))
1399 assertImageRange(aDestRange,mpImpl->maBounds);
1400 assertImageRange(aSrcRange,aSrcBounds);
1402 drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode );
1406 void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1407 const basegfx::B2IRange& rSrcRect,
1408 const basegfx::B2IRange& rDstRect,
1409 DrawMode drawMode,
1410 const BitmapDeviceSharedPtr& rClip )
1412 if( !rClip )
1414 drawBitmap(rSrcBitmap,rSrcRect,rDstRect,drawMode);
1415 return;
1418 const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1419 const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1420 basegfx::B2IRange aSrcRange( rSrcRect );
1421 basegfx::B2IRange aDestRange( rDstRect );
1423 if( clipAreaImpl( aDestRange,
1424 aSrcRange,
1425 mpImpl->maBounds,
1426 aSrcBounds ))
1428 assertImageRange(aDestRange,mpImpl->maBounds);
1429 assertImageRange(aSrcRange,aSrcBounds);
1431 if( isCompatibleClipMask( rClip ) )
1433 drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode, rClip );
1435 else
1437 getGenericRenderer()->drawBitmap( rSrcBitmap, rSrcRect,
1438 rDstRect, drawMode, rClip );
1443 void BitmapDevice::drawMaskedColor( Color aSrcColor,
1444 const BitmapDeviceSharedPtr& rAlphaMask,
1445 const basegfx::B2IRange& rSrcRect,
1446 const basegfx::B2IPoint& rDstPoint )
1448 const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
1449 const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1450 basegfx::B2IRange aSrcRange( rSrcRect );
1451 basegfx::B2IPoint aDestPoint( rDstPoint );
1453 if( clipAreaImpl( aSrcRange,
1454 aDestPoint,
1455 aSrcBounds,
1456 mpImpl->maBounds ))
1458 assertImagePoint(aDestPoint,mpImpl->maBounds);
1459 assertImageRange(aSrcRange,aSrcBounds);
1461 if( rAlphaMask.get() == this )
1463 // src == dest, copy rAlphaMask beforehand
1464 // ---------------------------------------------------
1466 const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
1467 aSrcRange.getHeight() );
1468 BitmapDeviceSharedPtr pAlphaCopy(
1469 cloneBitmapDevice( aSize,
1470 shared_from_this()) );
1471 basegfx::B2ITuple aGcc3WorkaroundTemporary;
1472 const basegfx::B2IRange aAlphaRange( aGcc3WorkaroundTemporary,
1473 aSize );
1474 pAlphaCopy->drawBitmap(rAlphaMask,
1475 aSrcRange,
1476 aAlphaRange,
1477 DrawMode_PAINT);
1478 drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint );
1480 else
1482 drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint );
1487 void BitmapDevice::drawMaskedColor( Color aSrcColor,
1488 const BitmapDeviceSharedPtr& rAlphaMask,
1489 const basegfx::B2IRange& rSrcRect,
1490 const basegfx::B2IPoint& rDstPoint,
1491 const BitmapDeviceSharedPtr& rClip )
1493 if( !rClip )
1495 drawMaskedColor(aSrcColor,rAlphaMask,rSrcRect,rDstPoint);
1496 return;
1499 const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
1500 const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1501 basegfx::B2IRange aSrcRange( rSrcRect );
1502 basegfx::B2IPoint aDestPoint( rDstPoint );
1504 if( clipAreaImpl( aSrcRange,
1505 aDestPoint,
1506 aSrcBounds,
1507 mpImpl->maBounds ))
1509 assertImagePoint(aDestPoint,mpImpl->maBounds);
1510 assertImageRange(aSrcRange,aSrcBounds);
1512 if( isCompatibleClipMask( rClip ) )
1514 if( rAlphaMask.get() == this )
1516 // src == dest, copy rAlphaMask beforehand
1517 // ---------------------------------------------------
1519 const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
1520 aSrcRange.getHeight() );
1521 BitmapDeviceSharedPtr pAlphaCopy(
1522 cloneBitmapDevice( aSize,
1523 shared_from_this()) );
1524 basegfx::B2ITuple aGcc3WorkaroundTemporary;
1525 const basegfx::B2IRange aAlphaRange( aGcc3WorkaroundTemporary,
1526 aSize );
1527 pAlphaCopy->drawBitmap(rAlphaMask,
1528 aSrcRange,
1529 aAlphaRange,
1530 DrawMode_PAINT);
1531 drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint, rClip );
1533 else
1535 drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint, rClip );
1538 else
1540 getGenericRenderer()->drawMaskedColor( aSrcColor, rAlphaMask,
1541 rSrcRect, rDstPoint, rClip );
1546 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1547 const BitmapDeviceSharedPtr& rMask,
1548 const basegfx::B2IRange& rSrcRect,
1549 const basegfx::B2IRange& rDstRect,
1550 DrawMode drawMode )
1552 OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
1554 const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1555 const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1556 basegfx::B2IRange aSrcRange( rSrcRect );
1557 basegfx::B2IRange aDestRange( rDstRect );
1559 if( clipAreaImpl( aDestRange,
1560 aSrcRange,
1561 mpImpl->maBounds,
1562 aSrcBounds ))
1564 assertImageRange(aDestRange,mpImpl->maBounds);
1565 assertImageRange(aSrcRange,aSrcBounds);
1567 drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode );
1571 void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1572 const BitmapDeviceSharedPtr& rMask,
1573 const basegfx::B2IRange& rSrcRect,
1574 const basegfx::B2IRange& rDstRect,
1575 DrawMode drawMode,
1576 const BitmapDeviceSharedPtr& rClip )
1578 if( !rClip )
1580 drawMaskedBitmap(rSrcBitmap,rMask,rSrcRect,rDstRect,drawMode);
1581 return;
1584 OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
1586 const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1587 const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1588 basegfx::B2IRange aSrcRange( rSrcRect );
1589 basegfx::B2IRange aDestRange( rDstRect );
1591 if( clipAreaImpl( aDestRange,
1592 aSrcRange,
1593 mpImpl->maBounds,
1594 aSrcBounds ))
1596 assertImageRange(aDestRange,mpImpl->maBounds);
1597 assertImageRange(aSrcRange,aSrcBounds);
1599 if( isCompatibleClipMask( rClip ) )
1601 drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode, rClip );
1603 else
1605 getGenericRenderer()->drawMaskedBitmap( rSrcBitmap, rMask, rSrcRect,
1606 rDstRect, drawMode, rClip );
1612 //----------------------------------------------------------------------------------
1614 /** Standard clip and alpha masks
1616 struct StdMasks
1618 typedef PixelFormatTraits_GREY1_MSB clipmask_format_traits;
1619 typedef PixelFormatTraits_GREY8 alphamask_format_traits;
1621 /// Clipmask: 0 means opaque
1622 static const bool clipmask_polarity = false;
1624 /// Alpha mask: 0 means fully transparent
1625 static const bool alphamask_polarity = true;
1628 #if 0
1629 /** Clip and alpha masks for the generic renderer (of course, those
1630 need to be generic, too)
1632 struct MaskTraitsGeneric
1634 typedef PixelFormatTraits_GenericInteger clipmask_format_traits;
1635 typedef PixelFormatTraits_GenericInteger alphamask_format_traits;
1637 #endif
1639 //----------------------------------------------------------------------------------
1641 // Some compilers don't like the nested template wrap_accessor
1642 // reference in the parameter list - being slightly less type safe,
1643 // then.
1644 #ifndef BASEBMP_NO_NESTED_TEMPLATE_PARAMETER
1646 /// Produces a specialized renderer for the given pixel format
1647 template< class FormatTraits, class MaskTraits >
1648 BitmapDeviceSharedPtr createRenderer(
1649 const basegfx::B2IRange& rBounds,
1650 sal_Int32 nScanlineFormat,
1651 sal_Int32 nScanlineStride,
1652 sal_uInt8* pFirstScanline,
1653 typename FormatTraits::raw_accessor_type const& rRawAccessor,
1654 typename FormatTraits::accessor_selector::template wrap_accessor<
1655 typename FormatTraits::raw_accessor_type>::type const& rAccessor,
1656 boost::shared_array< sal_uInt8 > pMem,
1657 const PaletteMemorySharedVector& pPal )
1659 #else
1661 template< class FormatTraits, class MaskTraits, class Accessor >
1662 BitmapDeviceSharedPtr createRenderer(
1663 const basegfx::B2IRange& rBounds,
1664 sal_Int32 nScanlineFormat,
1665 sal_Int32 nScanlineStride,
1666 sal_uInt8* pFirstScanline,
1667 typename FormatTraits::raw_accessor_type const& rRawAccessor,
1668 Accessor const& rAccessor,
1669 boost::shared_array< sal_uInt8 > pMem,
1670 const PaletteMemorySharedVector& pPal )
1672 #endif
1674 typedef typename FormatTraits::iterator_type Iterator;
1675 typedef BitmapRenderer< Iterator,
1676 typename FormatTraits::raw_accessor_type,
1677 typename FormatTraits::accessor_selector,
1678 MaskTraits > Renderer;
1680 return BitmapDeviceSharedPtr(
1681 new Renderer( rBounds,
1682 nScanlineFormat,
1683 nScanlineStride,
1684 pFirstScanline,
1685 Iterator(
1686 reinterpret_cast<typename Iterator::value_type*>(
1687 pFirstScanline),
1688 nScanlineStride),
1689 rRawAccessor,
1690 rAccessor,
1691 pMem,
1692 pPal ));
1695 /// Create standard grey level palette
1696 PaletteMemorySharedVector createStandardPalette(
1697 const PaletteMemorySharedVector& pPal,
1698 sal_Int32 nNumEntries )
1700 if( pPal || nNumEntries <= 0 )
1701 return pPal;
1703 boost::shared_ptr< std::vector<Color> > pLocalPal(
1704 new std::vector<Color>(nNumEntries) );
1706 const sal_Int32 nIncrement( 0x00FFFFFF/nNumEntries );
1707 --nNumEntries;
1708 for( sal_Int32 i=0, c=0; i<nNumEntries; ++i,c+=nIncrement )
1709 pLocalPal->at(i) = Color(0xFF000000 | c);
1711 pLocalPal->at(nNumEntries) = Color(0xFFFFFFFF);
1713 return pLocalPal;
1716 template< class FormatTraits, class MaskTraits >
1717 BitmapDeviceSharedPtr createRenderer(
1718 const basegfx::B2IRange& rBounds,
1719 sal_Int32 nScanlineFormat,
1720 sal_Int32 nScanlineStride,
1721 sal_uInt8* pFirstScanline,
1722 boost::shared_array< sal_uInt8 > pMem,
1723 const PaletteMemorySharedVector& pPal )
1725 return createRenderer<FormatTraits,
1726 MaskTraits>(rBounds,
1727 nScanlineFormat,
1728 nScanlineStride,
1729 pFirstScanline,
1730 typename FormatTraits::raw_accessor_type(),
1731 typename FormatTraits::accessor_selector::template
1732 wrap_accessor<
1733 typename FormatTraits::raw_accessor_type>::type(),
1734 pMem,
1735 pPal);
1738 template< class FormatTraits, class MaskTraits >
1739 BitmapDeviceSharedPtr createRenderer(
1740 const basegfx::B2IRange& rBounds,
1741 sal_Int32 nScanlineFormat,
1742 sal_Int32 nScanlineStride,
1743 sal_uInt8* pFirstScanline,
1744 boost::shared_array< sal_uInt8 > pMem,
1745 PaletteMemorySharedVector pPal,
1746 int nBitsPerPixel )
1748 pPal = createStandardPalette(pPal,
1749 1UL << nBitsPerPixel);
1751 OSL_ASSERT(pPal);
1752 return createRenderer<FormatTraits,
1753 MaskTraits>(rBounds,
1754 nScanlineFormat,
1755 nScanlineStride,
1756 pFirstScanline,
1757 typename FormatTraits::raw_accessor_type(),
1758 typename FormatTraits::accessor_selector::template
1759 wrap_accessor<
1760 typename FormatTraits::raw_accessor_type>::type(
1761 &pPal->at(0),
1762 pPal->size()),
1763 pMem,
1764 pPal);
1767 //----------------------------------------------------------------------------------
1769 // TODO(Q3): consolidate with canvas/canvastools.hxx! Best move this
1770 // to o3tl or sal/bithacks.hxx ...
1772 /** Compute the next highest power of 2 of a 32-bit value
1774 Code devised by Sean Anderson, in good ole HAKMEM
1775 tradition.
1777 @return 1 << (lg(x - 1) + 1)
1779 inline sal_uInt32 nextPow2( sal_uInt32 x )
1781 --x;
1782 x |= x >> 1;
1783 x |= x >> 2;
1784 x |= x >> 4;
1785 x |= x >> 8;
1786 x |= x >> 16;
1788 return ++x;
1791 //----------------------------------------------------------------------------------
1793 namespace
1795 BitmapDeviceSharedPtr createBitmapDeviceImpl( const basegfx::B2IVector& rSize,
1796 bool bTopDown,
1797 sal_Int32 nScanlineFormat,
1798 boost::shared_array< sal_uInt8 > pMem,
1799 PaletteMemorySharedVector pPal,
1800 const basegfx::B2IRange* pSubset )
1802 if( nScanlineFormat <= Format::NONE ||
1803 nScanlineFormat > Format::MAX )
1804 return BitmapDeviceSharedPtr();
1806 static const sal_uInt8 bitsPerPixel[] =
1808 0, // NONE
1809 1, // ONE_BIT_MSB_GREY
1810 1, // ONE_BIT_LSB_GREY
1811 1, // ONE_BIT_MSB_PAL
1812 1, // ONE_BIT_LSB_PAL
1813 4, // FOUR_BIT_MSB_GREY
1814 4, // FOUR_BIT_LSB_GREY
1815 4, // FOUR_BIT_MSB_PAL
1816 4, // FOUR_BIT_LSB_PAL
1817 8, // EIGHT_BIT_PAL
1818 8, // EIGHT_BIT_GREY
1819 16, // SIXTEEN_BIT_LSB_TC_MASK
1820 16, // SIXTEEN_BIT_MSB_TC_MASK
1821 24, // TWENTYFOUR_BIT_TC_MASK
1822 32, // THIRTYTWO_BIT_TC_MASK
1823 32, // THIRTYTWO_BIT_TC_MASK_ARGB
1826 sal_Int32 nScanlineStride(0);
1828 // round up to full 8 bit, divide by 8
1829 nScanlineStride = (rSize.getX()*bitsPerPixel[nScanlineFormat] + 7) >> 3;
1831 // rounded up to next full power-of-two number of bytes
1832 const sal_uInt32 bytesPerPixel = nextPow2(
1833 (bitsPerPixel[nScanlineFormat] + 7) >> 3);
1835 // now make nScanlineStride a multiple of bytesPerPixel
1836 nScanlineStride = (nScanlineStride + bytesPerPixel - 1) / bytesPerPixel * bytesPerPixel;
1838 // factor in bottom-up scanline order case
1839 nScanlineStride *= bTopDown ? 1 : -1;
1841 const std::size_t nMemSize(
1842 (nScanlineStride < 0 ? -nScanlineStride : nScanlineStride)*rSize.getY() );
1844 if( !pMem )
1846 pMem.reset(
1847 reinterpret_cast<sal_uInt8*>(rtl_allocateMemory( nMemSize )),
1848 &rtl_freeMemory );
1849 rtl_zeroMemory(pMem.get(),nMemSize);
1852 sal_uInt8* pFirstScanline = nScanlineStride < 0 ?
1853 pMem.get() + nMemSize + nScanlineStride : pMem.get();
1855 // shrink render area to given subset, if given
1856 basegfx::B2IRange aBounds(0,0,rSize.getX(),rSize.getY());
1857 if( pSubset )
1858 aBounds.intersect( *pSubset );
1860 switch( nScanlineFormat )
1862 // ----------------------------------------------------------------------
1863 // one bit formats
1865 case Format::ONE_BIT_MSB_GREY:
1866 return createRenderer<PixelFormatTraits_GREY1_MSB,StdMasks>(
1867 aBounds, nScanlineFormat, nScanlineStride,
1868 pFirstScanline, pMem, pPal );
1870 case Format::ONE_BIT_LSB_GREY:
1871 return createRenderer<PixelFormatTraits_GREY1_LSB,StdMasks>(
1872 aBounds, nScanlineFormat, nScanlineStride,
1873 pFirstScanline, pMem, pPal );
1875 case Format::ONE_BIT_MSB_PAL:
1876 return createRenderer<PixelFormatTraits_PAL1_MSB,StdMasks>(
1877 aBounds, nScanlineFormat, nScanlineStride,
1878 pFirstScanline, pMem, pPal,
1879 bitsPerPixel[nScanlineFormat] );
1881 case Format::ONE_BIT_LSB_PAL:
1882 return createRenderer<PixelFormatTraits_PAL1_LSB,StdMasks>(
1883 aBounds, nScanlineFormat, nScanlineStride,
1884 pFirstScanline, pMem, pPal,
1885 bitsPerPixel[nScanlineFormat] );
1888 // ----------------------------------------------------------------------
1889 // four bit formats
1891 case Format::FOUR_BIT_MSB_GREY:
1892 return createRenderer<PixelFormatTraits_GREY4_MSB,StdMasks>(
1893 aBounds, nScanlineFormat, nScanlineStride,
1894 pFirstScanline, pMem, pPal );
1896 case Format::FOUR_BIT_LSB_GREY:
1897 return createRenderer<PixelFormatTraits_GREY4_LSB,StdMasks>(
1898 aBounds, nScanlineFormat, nScanlineStride,
1899 pFirstScanline, pMem, pPal );
1901 case Format::FOUR_BIT_MSB_PAL:
1902 return createRenderer<PixelFormatTraits_PAL4_MSB,StdMasks>(
1903 aBounds, nScanlineFormat, nScanlineStride,
1904 pFirstScanline, pMem, pPal,
1905 bitsPerPixel[nScanlineFormat] );
1907 case Format::FOUR_BIT_LSB_PAL:
1908 return createRenderer<PixelFormatTraits_PAL4_LSB,StdMasks>(
1909 aBounds, nScanlineFormat, nScanlineStride,
1910 pFirstScanline, pMem, pPal,
1911 bitsPerPixel[nScanlineFormat] );
1914 // ----------------------------------------------------------------------
1915 // eight bit formats
1917 case Format::EIGHT_BIT_GREY:
1918 return createRenderer<PixelFormatTraits_GREY8,StdMasks>(
1919 aBounds, nScanlineFormat, nScanlineStride,
1920 pFirstScanline, pMem, pPal );
1922 case Format::EIGHT_BIT_PAL:
1923 return createRenderer<PixelFormatTraits_PAL8,StdMasks>(
1924 aBounds, nScanlineFormat, nScanlineStride,
1925 pFirstScanline, pMem, pPal,
1926 bitsPerPixel[nScanlineFormat] );
1929 // ----------------------------------------------------------------------
1930 // sixteen bit formats
1932 case Format::SIXTEEN_BIT_LSB_TC_MASK:
1933 return createRenderer<PixelFormatTraits_RGB16_565_LSB,StdMasks>(
1934 aBounds, nScanlineFormat, nScanlineStride,
1935 pFirstScanline, pMem, pPal );
1937 case Format::SIXTEEN_BIT_MSB_TC_MASK:
1938 return createRenderer<PixelFormatTraits_RGB16_565_MSB,StdMasks>(
1939 aBounds, nScanlineFormat, nScanlineStride,
1940 pFirstScanline, pMem, pPal );
1943 // ----------------------------------------------------------------------
1944 // twentyfour bit formats
1945 case Format::TWENTYFOUR_BIT_TC_MASK:
1946 return createRenderer<PixelFormatTraits_BGR24,StdMasks>(
1947 aBounds, nScanlineFormat, nScanlineStride,
1948 pFirstScanline, pMem, pPal );
1951 // ----------------------------------------------------------------------
1952 // thirtytwo bit formats
1954 case Format::THIRTYTWO_BIT_TC_MASK:
1955 return createRenderer<PixelFormatTraits_RGB32_888,StdMasks>(
1956 aBounds, nScanlineFormat, nScanlineStride,
1957 pFirstScanline, pMem, pPal );
1959 case Format::THIRTYTWO_BIT_TC_MASK_ARGB:
1960 return createRenderer<PixelFormatTraits_BGR32_888,StdMasks>(
1961 aBounds, nScanlineFormat, nScanlineStride,
1962 pFirstScanline, pMem, pPal );
1965 // TODO(F3): other formats not yet implemented
1966 return BitmapDeviceSharedPtr();
1968 } // namespace
1971 BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
1972 bool bTopDown,
1973 sal_Int32 nScanlineFormat )
1975 return createBitmapDeviceImpl( rSize,
1976 bTopDown,
1977 nScanlineFormat,
1978 boost::shared_array< sal_uInt8 >(),
1979 PaletteMemorySharedVector(),
1980 NULL );
1983 BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
1984 bool bTopDown,
1985 sal_Int32 nScanlineFormat,
1986 const PaletteMemorySharedVector& rPalette )
1988 return createBitmapDeviceImpl( rSize,
1989 bTopDown,
1990 nScanlineFormat,
1991 boost::shared_array< sal_uInt8 >(),
1992 rPalette,
1993 NULL );
1996 BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
1997 bool bTopDown,
1998 sal_Int32 nScanlineFormat,
1999 const RawMemorySharedArray& rMem,
2000 const PaletteMemorySharedVector& rPalette )
2002 return createBitmapDeviceImpl( rSize,
2003 bTopDown,
2004 nScanlineFormat,
2005 rMem,
2006 rPalette,
2007 NULL );
2010 BitmapDeviceSharedPtr subsetBitmapDevice( const BitmapDeviceSharedPtr& rProto,
2011 const basegfx::B2IRange& rSubset )
2013 return createBitmapDeviceImpl( rProto->getSize(),
2014 rProto->isTopDown(),
2015 rProto->getScanlineFormat(),
2016 rProto->getBuffer(),
2017 rProto->getPalette(),
2018 &rSubset );
2021 BitmapDeviceSharedPtr cloneBitmapDevice( const basegfx::B2IVector& rSize,
2022 const BitmapDeviceSharedPtr& rProto )
2024 return createBitmapDeviceImpl( rSize,
2025 rProto->isTopDown(),
2026 rProto->getScanlineFormat(),
2027 boost::shared_array< sal_uInt8 >(),
2028 rProto->getPalette(),
2029 NULL );
2032 //----------------------------------------------------------------------------------
2034 /// Clone our device, with GenericImageAccessor to handle all formats
2035 BitmapDeviceSharedPtr BitmapDevice::getGenericRenderer() const
2037 #if 0
2038 // xxx TODO
2039 typedef BitmapRenderer< PixelFormatTraits_GenericInteger::iterator_type,
2040 PixelFormatTraits_GenericInteger::raw_accessor_type,
2041 PixelFormatTraits_GenericInteger::accessor_selector,
2042 MaskTraitsGeneric >
2043 Renderer;
2045 if( !mpImpl->mpGenericRenderer )
2047 mpImpl->mpGenericRenderer.reset(
2048 new Renderer(
2049 mpImpl->maBounds,
2050 isTopDown(),
2051 getScanlineFormat(),
2052 getScanlineStride(),
2053 mpImpl->mpFirstScanline,
2054 PixelFormatTraits_GenericInteger::iterator_type(),
2055 GenericIntegerImageRawAccessor<Color>(
2056 const_cast<BitmapDevice*>(this)->shared_from_this()),
2057 GenericIntegerImageAccessor<Color>(
2058 const_cast<BitmapDevice*>(this)->shared_from_this()),
2059 getBuffer(),
2060 getPalette() ));
2062 #endif
2064 return mpImpl->mpGenericRenderer;
2067 } // namespace basebmp