Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <cassert>
23 : #include <string.h>
24 :
25 : #include <basebmp/bitmapdevice.hxx>
26 :
27 : #include <basebmp/compositeiterator.hxx>
28 : #include <basebmp/iteratortraits.hxx>
29 :
30 : #include <basebmp/accessor.hxx>
31 : #include <basebmp/accessortraits.hxx>
32 : #include <basebmp/accessoradapters.hxx>
33 : #include <basebmp/colorblendaccessoradapter.hxx>
34 :
35 : #include <basebmp/color.hxx>
36 : #include <basebmp/colormisc.hxx>
37 : #include <basebmp/colortraits.hxx>
38 :
39 : #include <basebmp/greylevelformats.hxx>
40 : #include <basebmp/paletteformats.hxx>
41 : #include <basebmp/rgbmaskpixelformats.hxx>
42 : #include <basebmp/rgb24pixelformats.hxx>
43 :
44 : #include <basebmp/scanlineformats.hxx>
45 : #include <basebmp/fillimage.hxx>
46 : #include <basebmp/scaleimage.hxx>
47 : #include <basebmp/clippedlinerenderer.hxx>
48 : #include <basebmp/polypolygonrenderer.hxx>
49 : #include <basebmp/genericcolorimageaccessor.hxx>
50 :
51 : #include <basebmp/tools.hxx>
52 : #include "intconversion.hxx"
53 :
54 : #include <rtl/alloc.h>
55 : #include <osl/diagnose.h>
56 :
57 : #include <basegfx/tools/tools.hxx>
58 : #include <basegfx/tools/canvastools.hxx>
59 : #include <basegfx/range/b2ibox.hxx>
60 : #include <basegfx/range/b2irange.hxx>
61 : #include <basegfx/range/b2drange.hxx>
62 : #include <basegfx/polygon/b2dpolygon.hxx>
63 : #include <basegfx/polygon/b2dpolygontools.hxx>
64 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
65 : #include <basegfx/point/b2ipoint.hxx>
66 : #include <basegfx/vector/b2ivector.hxx>
67 :
68 : #include <vigra/iteratortraits.hxx>
69 : #include <vigra/rgbvalue.hxx>
70 : #include <vigra/copyimage.hxx>
71 : #include <vigra/tuple.hxx>
72 :
73 :
74 : namespace vigra
75 : {
76 :
77 : /// componentwise xor of an RGBValue (missing from rgbvalue.hxx)
78 : template< class Value, unsigned int RedIndex, unsigned int BlueIndex, unsigned int GreenIndex >
79 : inline RGBValue<Value, RedIndex, GreenIndex, BlueIndex>
80 19575503 : operator^( RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& lhs,
81 : RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& rhs )
82 : {
83 : RGBValue<Value, RedIndex, GreenIndex, BlueIndex> res(
84 39151006 : lhs[0] ^ rhs[0],
85 39151006 : lhs[1] ^ rhs[1],
86 97877515 : lhs[2] ^ rhs[2]);
87 19575503 : return res;
88 : }
89 : }
90 :
91 : namespace basebmp
92 : {
93 :
94 : static const sal_uInt8 bitsPerPixel[] =
95 : {
96 : 0, // NONE
97 : 1, // ONE_BIT_MSB_GREY
98 : 1, // ONE_BIT_LSB_GREY
99 : 1, // ONE_BIT_MSB_PAL
100 : 1, // ONE_BIT_LSB_PAL
101 : 4, // FOUR_BIT_MSB_GREY
102 : 4, // FOUR_BIT_LSB_GREY
103 : 4, // FOUR_BIT_MSB_PAL
104 : 4, // FOUR_BIT_LSB_PAL
105 : 8, // EIGHT_BIT_PAL
106 : 8, // EIGHT_BIT_GREY
107 : 16, // SIXTEEN_BIT_LSB_TC_MASK
108 : 16, // SIXTEEN_BIT_MSB_TC_MASK
109 : 24, // TWENTYFOUR_BIT_TC_MASK
110 : 32, // THIRTYTWO_BIT_TC_MASK_BGRA
111 : 32, // THIRTYTWO_BIT_TC_MASK_ARGB
112 : 32, // THIRTYTWO_BIT_TC_MASK_ABGR
113 : 32, // THIRTYTWO_BIT_TC_MASK_RGBA
114 : };
115 :
116 : namespace
117 : {
118 : /** Create the type for an accessor that takes the (mask,bitmap)
119 : input value generated from a JoinImageAccessorAdapter, and
120 : pipe that through a mask functor.
121 :
122 : @tpl DestAccessor
123 : Destination bitmap accessor
124 :
125 : @tpl JoinedAccessor
126 : Input accessor, is expected to generate a std::pair as the
127 : value type
128 :
129 : @tpl MaskFunctorMode
130 : Either FastMask or NoFastMask, depending on whether the mask
131 : is guaranteed to contain only 0s and 1s.
132 : */
133 : template< class DestAccessor,
134 : class JoinedAccessor,
135 : bool polarity,
136 : typename MaskFunctorMode > struct masked_input_splitting_accessor
137 : {
138 : typedef BinarySetterFunctionAccessorAdapter<
139 : DestAccessor,
140 : BinaryFunctorSplittingWrapper<
141 : typename outputMaskFunctorSelector<
142 : typename JoinedAccessor::value_type::first_type,
143 : typename JoinedAccessor::value_type::second_type,
144 : polarity,
145 : MaskFunctorMode >::type > > type;
146 : };
147 :
148 :
149 :
150 : // Actual BitmapDevice implementation (templatized by accessor and iterator)
151 :
152 : /** Implementation of the BitmapDevice interface
153 :
154 : @tpl DestIterator
155 : Iterator to access bitmap memory
156 :
157 : @tpl RawAccessor
158 : Raw accessor, to access pixel values directly
159 :
160 : @tpl AccessorSelector
161 : Accessor adapter selector, which, when applying the nested
162 : template metafunction wrap_accessor to one of the raw bitmap
163 : accessors, yields a member type named 'type', which is a
164 : wrapped accessor that map color values.
165 :
166 : @tpl Masks
167 : Traits template, containing nested traits
168 : clipmask_format_traits and alphamask_format_traits, which
169 : determine what specialized formats are to be used for clip and
170 : alpha masks. With those mask formats, clipping and alpha
171 : blending is handled natively.
172 : */
173 : template< class DestIterator,
174 : class RawAccessor,
175 : class AccessorSelector,
176 3613086 : class Masks > class BitmapRenderer :
177 : public BitmapDevice
178 : {
179 : public:
180 : typedef DestIterator dest_iterator_type;
181 : typedef RawAccessor raw_accessor_type;
182 : typedef AccessorSelector accessor_selector;
183 :
184 : typedef typename Masks::clipmask_format_traits::iterator_type mask_iterator_type;
185 : typedef typename Masks::clipmask_format_traits::raw_accessor_type mask_rawaccessor_type;
186 : typedef typename Masks::clipmask_format_traits::accessor_selector mask_accessorselector_type;
187 :
188 : typedef typename Masks::alphamask_format_traits::iterator_type alphamask_iterator_type;
189 : typedef typename Masks::alphamask_format_traits::raw_accessor_type alphamask_rawaccessor_type;
190 : typedef typename Masks::alphamask_format_traits::accessor_selector alphamask_accessorselector_type;
191 :
192 : typedef typename AccessorSelector::template wrap_accessor<
193 : raw_accessor_type >::type dest_accessor_type;
194 :
195 : typedef AccessorTraits< dest_accessor_type > accessor_traits;
196 : typedef CompositeIterator2D< dest_iterator_type,
197 : mask_iterator_type > composite_iterator_type;
198 : typedef CompositeIterator2D< vigra::Diff2D,
199 : vigra::Diff2D > generic_composite_iterator_type;
200 :
201 : typedef BitmapRenderer<mask_iterator_type,
202 : mask_rawaccessor_type,
203 : mask_accessorselector_type,
204 : Masks> mask_bitmap_type;
205 : typedef BitmapRenderer<alphamask_iterator_type,
206 : alphamask_rawaccessor_type,
207 : alphamask_accessorselector_type,
208 : Masks> alphamask_bitmap_type;
209 :
210 :
211 :
212 : typedef AccessorTraits< raw_accessor_type > raw_accessor_traits;
213 : typedef typename uInt32Converter<
214 : typename raw_accessor_type::value_type>::to to_uint32_functor;
215 :
216 :
217 :
218 : typedef typename raw_accessor_traits::xor_accessor raw_xor_accessor_type;
219 : typedef AccessorTraits<raw_xor_accessor_type> raw_xor_accessor_traits;
220 : typedef typename accessor_selector::template wrap_accessor<
221 : raw_xor_accessor_type >::type xor_accessor_type;
222 : typedef AccessorTraits<xor_accessor_type> xor_accessor_traits;
223 :
224 :
225 :
226 : typedef typename raw_accessor_traits::template masked_accessor<
227 : mask_rawaccessor_type,
228 : dest_iterator_type,
229 : mask_iterator_type,
230 : Masks::clipmask_polarity>::type raw_maskedaccessor_type;
231 : typedef typename accessor_selector::template wrap_accessor<
232 : raw_maskedaccessor_type >::type masked_accessor_type;
233 : typedef typename AccessorTraits<
234 : raw_maskedaccessor_type>::xor_accessor raw_maskedxor_accessor_type;
235 : typedef typename accessor_selector::template wrap_accessor<
236 : raw_maskedxor_accessor_type >::type masked_xoraccessor_type;
237 :
238 :
239 :
240 : // ((iter,mask),mask) special case (e.g. for clipped
241 : // drawMaskedColor())
242 : typedef AccessorTraits< raw_maskedaccessor_type > raw_maskedaccessor_traits;
243 : typedef typename raw_maskedaccessor_traits::template masked_accessor<
244 : mask_rawaccessor_type,
245 : composite_iterator_type,
246 : mask_iterator_type,
247 : Masks::clipmask_polarity>::type raw_maskedmask_accessor_type;
248 :
249 : typedef CompositeIterator2D<
250 : composite_iterator_type,
251 : mask_iterator_type> composite_composite_mask_iterator_type;
252 :
253 :
254 :
255 : typedef ConstantColorBlendSetterAccessorAdapter<
256 : dest_accessor_type,
257 : typename alphamask_rawaccessor_type::value_type,
258 : Masks::alphamask_polarity> colorblend_accessor_type;
259 : typedef AccessorTraits<colorblend_accessor_type> colorblend_accessor_traits;
260 : typedef typename colorblend_accessor_traits::template masked_accessor<
261 : mask_rawaccessor_type,
262 : dest_iterator_type,
263 : mask_iterator_type,
264 : Masks::clipmask_polarity>::type masked_colorblend_accessor_type;
265 :
266 :
267 :
268 : typedef ConstantColorBlendSetterAccessorAdapter<
269 : dest_accessor_type,
270 : Color,
271 : Masks::alphamask_polarity> colorblend_generic_accessor_type;
272 : typedef AccessorTraits<colorblend_generic_accessor_type> colorblend_generic_accessor_traits;
273 : typedef typename colorblend_generic_accessor_traits::template masked_accessor<
274 : mask_rawaccessor_type,
275 : dest_iterator_type,
276 : mask_iterator_type,
277 : Masks::clipmask_polarity>::type masked_colorblend_generic_accessor_type;
278 :
279 :
280 :
281 : typedef JoinImageAccessorAdapter< dest_accessor_type,
282 : mask_rawaccessor_type > joined_image_accessor_type;
283 : typedef JoinImageAccessorAdapter< GenericColorImageAccessor,
284 : GenericColorImageAccessor > joined_generic_image_accessor_type;
285 :
286 :
287 :
288 : dest_iterator_type maBegin;
289 : typename accessor_traits::color_lookup maColorLookup;
290 : IBitmapDeviceDamageTrackerSharedPtr mpDamage;
291 : to_uint32_functor maToUInt32Converter;
292 : dest_accessor_type maAccessor;
293 : colorblend_accessor_type maColorBlendAccessor;
294 : colorblend_generic_accessor_type maGenericColorBlendAccessor;
295 : raw_accessor_type maRawAccessor;
296 : xor_accessor_type maXorAccessor;
297 : raw_xor_accessor_type maRawXorAccessor;
298 : masked_accessor_type maMaskedAccessor;
299 : masked_colorblend_accessor_type maMaskedColorBlendAccessor;
300 : masked_colorblend_generic_accessor_type maGenericMaskedColorBlendAccessor;
301 : masked_xoraccessor_type maMaskedXorAccessor;
302 : raw_maskedaccessor_type maRawMaskedAccessor;
303 : raw_maskedxor_accessor_type maRawMaskedXorAccessor;
304 : raw_maskedmask_accessor_type maRawMaskedMaskAccessor;
305 :
306 :
307 :
308 :
309 1830472 : BitmapRenderer( const basegfx::B2IBox& rBounds,
310 : const basegfx::B2IVector& rBufferSize,
311 : Format nScanlineFormat,
312 : sal_Int32 nScanlineStride,
313 : sal_uInt8* pFirstScanline,
314 : dest_iterator_type begin,
315 : raw_accessor_type rawAccessor,
316 : dest_accessor_type accessor,
317 : const RawMemorySharedArray& rMem,
318 : const PaletteMemorySharedVector& rPalette,
319 : const IBitmapDeviceDamageTrackerSharedPtr& rDamage ) :
320 : BitmapDevice( rBounds, rBufferSize, nScanlineFormat,
321 : nScanlineStride, pFirstScanline, rMem, rPalette ),
322 : maBegin( begin ),
323 : maColorLookup(),
324 : mpDamage(rDamage),
325 : maToUInt32Converter(),
326 : maAccessor( accessor ),
327 : maColorBlendAccessor( accessor ),
328 : maGenericColorBlendAccessor( accessor ),
329 : maRawAccessor( rawAccessor ),
330 : maXorAccessor( accessor ),
331 : maRawXorAccessor( rawAccessor ),
332 : maMaskedAccessor( accessor ),
333 : maMaskedColorBlendAccessor( maColorBlendAccessor ),
334 : maGenericMaskedColorBlendAccessor( maGenericColorBlendAccessor ),
335 : maMaskedXorAccessor( accessor ),
336 : maRawMaskedAccessor( rawAccessor ),
337 : maRawMaskedXorAccessor( rawAccessor ),
338 1830472 : maRawMaskedMaskAccessor( rawAccessor )
339 1830472 : {}
340 :
341 : private:
342 :
343 5234534 : void damaged( const basegfx::B2IBox& rDamageRect ) const
344 : {
345 5234534 : if( mpDamage )
346 0 : mpDamage->damaged( rDamageRect );
347 5234534 : }
348 :
349 2293658 : void damagedPointSize( const basegfx::B2IPoint& rPoint,
350 : const basegfx::B2IBox& rSize ) const
351 : {
352 2293658 : if( mpDamage ) {
353 0 : basegfx::B2IPoint aLower( rPoint.getX() + rSize.getWidth(),
354 0 : rPoint.getY() + rSize.getHeight() );
355 0 : damaged( basegfx::B2IBox( rPoint, aLower ) );
356 : }
357 2293658 : }
358 :
359 1326210 : void damagedPixel( const basegfx::B2IPoint& rDamagePoint ) const
360 : {
361 1326210 : if( !mpDamage )
362 2652420 : return;
363 :
364 0 : sal_Int32 nX(rDamagePoint.getX());
365 0 : sal_Int32 nY(rDamagePoint.getY());
366 0 : if (nX < SAL_MAX_INT32)
367 0 : ++nX;
368 0 : if (nY < SAL_MAX_INT32)
369 0 : ++nY;
370 :
371 0 : basegfx::B2IPoint aEnd( nX, nY );
372 0 : damaged( basegfx::B2IBox( rDamagePoint, aEnd ) );
373 : }
374 :
375 595412 : boost::shared_ptr<BitmapRenderer> getCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
376 : {
377 595412 : return boost::dynamic_pointer_cast< BitmapRenderer >( bmp );
378 : }
379 :
380 582402 : virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const SAL_OVERRIDE
381 : {
382 : // TODO(P1): dynamic_cast usually called twice for
383 : // compatible formats
384 582402 : return getCompatibleBitmap(bmp).get() != NULL;
385 : }
386 :
387 3003255 : boost::shared_ptr<mask_bitmap_type> getCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const
388 : {
389 3003255 : boost::shared_ptr<mask_bitmap_type> pMask( boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ));
390 :
391 3003255 : if( !pMask )
392 2293658 : return pMask;
393 :
394 709597 : if( pMask->getSize() != getSize() )
395 0 : pMask.reset();
396 :
397 709597 : return pMask;
398 : }
399 :
400 728912 : virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const SAL_OVERRIDE
401 : {
402 : // TODO(P1): dynamic_cast usually called twice for
403 : // compatible formats
404 728912 : return boost::dynamic_pointer_cast<mask_bitmap_type>( bmp ).get() != NULL;
405 : }
406 :
407 2293658 : boost::shared_ptr<alphamask_bitmap_type> getCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
408 : {
409 2293658 : return boost::dynamic_pointer_cast<alphamask_bitmap_type>( bmp );
410 : }
411 :
412 0 : virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const SAL_OVERRIDE
413 : {
414 : // TODO(P1): dynamic_cast usually called twice for
415 : // compatible formats
416 0 : return getCompatibleAlphaMask( bmp ).get() != NULL;
417 : }
418 :
419 148 : virtual void clear_i( Color fillColor,
420 : const basegfx::B2IBox& rBounds ) SAL_OVERRIDE
421 : {
422 148 : fillImage(destIterRange(maBegin,
423 : maRawAccessor,
424 148 : rBounds),
425 : maColorLookup(
426 : maAccessor,
427 444 : fillColor) );
428 148 : damaged( rBounds );
429 148 : }
430 :
431 768243 : virtual void setPixel_i( const basegfx::B2IPoint& rPt,
432 : Color pixelColor,
433 : DrawMode drawMode ) SAL_OVERRIDE
434 : {
435 1536486 : const DestIterator pixel( maBegin +
436 : vigra::Diff2D(rPt.getX(),
437 768243 : rPt.getY()) );
438 768243 : if( drawMode == DrawMode_XOR )
439 0 : maXorAccessor.set( pixelColor,
440 : pixel );
441 : else
442 768243 : maAccessor.set( pixelColor,
443 : pixel );
444 768243 : damagedPixel(rPt);
445 768243 : }
446 :
447 557967 : virtual void setPixel_i( const basegfx::B2IPoint& rPt,
448 : Color pixelColor,
449 : DrawMode drawMode,
450 : const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
451 : {
452 557967 : boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
453 : OSL_ASSERT( pMask );
454 :
455 : const vigra::Diff2D offset(rPt.getX(),
456 557967 : rPt.getY());
457 :
458 : const composite_iterator_type aIter(
459 557967 : maBegin + offset,
460 1115934 : pMask->maBegin + offset );
461 :
462 557967 : if( drawMode == DrawMode_XOR )
463 0 : maMaskedXorAccessor.set( pixelColor,
464 : aIter );
465 : else
466 557967 : maMaskedAccessor.set( pixelColor,
467 : aIter );
468 557967 : damagedPixel(rPt);
469 557967 : }
470 :
471 123542882 : virtual Color getPixel_i(const basegfx::B2IPoint& rPt ) SAL_OVERRIDE
472 : {
473 247085764 : const DestIterator pixel( maBegin +
474 : vigra::Diff2D(rPt.getX(),
475 123542882 : rPt.getY()) );
476 123542882 : return maAccessor(pixel);
477 : }
478 :
479 8 : virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt ) SAL_OVERRIDE
480 : {
481 16 : const DestIterator pixel( maBegin +
482 : vigra::Diff2D(rPt.getX(),
483 8 : rPt.getY()) );
484 8 : return maToUInt32Converter(maRawAccessor(pixel));
485 : }
486 :
487 : template< typename Iterator, typename Col, typename RawAcc >
488 4596510 : void implRenderLine2( const basegfx::B2IPoint& rPt1,
489 : const basegfx::B2IPoint& rPt2,
490 : const basegfx::B2IBox& rBounds,
491 : Col col,
492 : const Iterator& begin,
493 : const RawAcc& rawAcc )
494 : {
495 4596510 : renderClippedLine( rPt1,
496 : rPt2,
497 : rBounds,
498 : col,
499 : begin,
500 9193020 : rawAcc );
501 : // TODO(P2): perhaps this needs pushing up the stack a bit
502 : // to make more complex polygons more efficient ...
503 4596510 : damaged( basegfx::B2IBox( rPt1, rPt2 ) );
504 4596510 : }
505 :
506 : template< typename Iterator, typename Accessor, typename RawAcc >
507 3330233 : void implRenderLine( const basegfx::B2IPoint& rPt1,
508 : const basegfx::B2IPoint& rPt2,
509 : const basegfx::B2IBox& rBounds,
510 : Color col,
511 : const Iterator& begin,
512 : const Accessor& acc,
513 : const RawAcc& rawAcc )
514 : {
515 3330233 : implRenderLine2( rPt1,rPt2,rBounds,
516 : maColorLookup( acc,
517 : col ),
518 : begin,
519 6660406 : rawAcc );
520 3330233 : }
521 :
522 : template< typename Iterator, typename RawAcc, typename XorAcc >
523 3330233 : void implDrawLine( const basegfx::B2IPoint& rPt1,
524 : const basegfx::B2IPoint& rPt2,
525 : const basegfx::B2IBox& rBounds,
526 : Color col,
527 : const Iterator& begin,
528 : const RawAcc& rawAcc,
529 : const XorAcc& xorAcc,
530 : DrawMode drawMode )
531 : {
532 3330233 : if( drawMode == DrawMode_XOR )
533 16 : implRenderLine( rPt1, rPt2, rBounds, col,
534 16 : begin, maAccessor, xorAcc );
535 : else
536 3330217 : implRenderLine( rPt1, rPt2, rBounds, col,
537 3330217 : begin, maAccessor, rawAcc );
538 3330233 : }
539 :
540 3244323 : virtual void drawLine_i(const basegfx::B2IPoint& rPt1,
541 : const basegfx::B2IPoint& rPt2,
542 : const basegfx::B2IBox& rBounds,
543 : Color lineColor,
544 : DrawMode drawMode ) SAL_OVERRIDE
545 : {
546 3244323 : implDrawLine(rPt1,rPt2,rBounds,lineColor,
547 : maBegin,
548 3244323 : maRawAccessor,maRawXorAccessor,drawMode);
549 3244323 : }
550 :
551 151622 : composite_iterator_type getMaskedIter( const BitmapDeviceSharedPtr& rClip ) const
552 : {
553 151622 : boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rClip) );
554 : OSL_ASSERT( pMask );
555 :
556 : return composite_iterator_type( maBegin,
557 151622 : pMask->maBegin );
558 : }
559 :
560 85910 : virtual void drawLine_i(const basegfx::B2IPoint& rPt1,
561 : const basegfx::B2IPoint& rPt2,
562 : const basegfx::B2IBox& rBounds,
563 : Color lineColor,
564 : DrawMode drawMode,
565 : const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
566 : {
567 85910 : implDrawLine(rPt1,rPt2,rBounds,lineColor,
568 : getMaskedIter(rClip),
569 : maRawMaskedAccessor,
570 171820 : maRawMaskedXorAccessor,drawMode);
571 85910 : }
572 :
573 : template< typename Iterator, typename RawAcc >
574 262774 : void implDrawPolygon( const basegfx::B2DPolygon& rPoly,
575 : const basegfx::B2IBox& rBounds,
576 : Color col,
577 : const Iterator& begin,
578 : const RawAcc& acc )
579 : {
580 262774 : basegfx::B2DPolygon aPoly( rPoly );
581 262774 : if( rPoly.areControlPointsUsed() )
582 0 : aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
583 :
584 : const typename dest_iterator_type::value_type colorIndex( maColorLookup(
585 : maAccessor,
586 262774 : col));
587 262774 : const sal_uInt32 nVertices( aPoly.count() );
588 1520238 : for( sal_uInt32 i=1; i<nVertices; ++i )
589 1257464 : implRenderLine2( basegfx::fround(aPoly.getB2DPoint(i-1)),
590 : basegfx::fround(aPoly.getB2DPoint(i)),
591 : rBounds,
592 : colorIndex,
593 : begin,
594 2514928 : acc );
595 :
596 262774 : if( nVertices > 1 && aPoly.isClosed() )
597 8813 : implRenderLine2( basegfx::fround(aPoly.getB2DPoint(nVertices-1)),
598 : basegfx::fround(aPoly.getB2DPoint(0)),
599 : rBounds,
600 : colorIndex,
601 : begin,
602 17626 : acc );
603 262774 : }
604 :
605 261264 : virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
606 : const basegfx::B2IBox& rBounds,
607 : Color lineColor,
608 : DrawMode drawMode ) SAL_OVERRIDE
609 : {
610 261264 : if( drawMode == DrawMode_XOR )
611 0 : implDrawPolygon( rPoly, rBounds, lineColor,
612 : maBegin,
613 0 : maRawXorAccessor );
614 : else
615 261264 : implDrawPolygon( rPoly, rBounds, lineColor,
616 : maBegin,
617 261264 : maRawAccessor );
618 261264 : }
619 :
620 1510 : virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
621 : const basegfx::B2IBox& rBounds,
622 : Color lineColor,
623 : DrawMode drawMode,
624 : const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
625 : {
626 1510 : if( drawMode == DrawMode_XOR )
627 0 : implDrawPolygon( rPoly, rBounds, lineColor,
628 : getMaskedIter(rClip),
629 0 : maRawMaskedXorAccessor );
630 : else
631 1510 : implDrawPolygon( rPoly, rBounds, lineColor,
632 : getMaskedIter(rClip),
633 3020 : maRawMaskedAccessor );
634 1510 : }
635 :
636 : template< typename Iterator, typename RawAcc >
637 4655917 : void implFillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
638 : Color col,
639 : const Iterator& begin,
640 : const RawAcc& acc,
641 : const basegfx::B2IBox& rBounds )
642 : {
643 4655917 : basegfx::B2DPolyPolygon aPoly( rPoly );
644 4655917 : if( rPoly.areControlPointsUsed() )
645 0 : aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly );
646 :
647 4655917 : renderClippedPolyPolygon( begin,
648 : acc,
649 : maColorLookup( maAccessor,
650 : col),
651 : rBounds,
652 : aPoly,
653 9169937 : basegfx::FillRule_EVEN_ODD );
654 :
655 4655917 : if( mpDamage )
656 : {
657 0 : basegfx::B2DRange const aPolyBounds( basegfx::tools::getRange(aPoly) );
658 0 : damaged( basegfx::unotools::b2ISurroundingBoxFromB2DRange( aPolyBounds ) );
659 4655917 : }
660 4655917 : }
661 :
662 4594481 : virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
663 : Color fillColor,
664 : DrawMode drawMode,
665 : const basegfx::B2IBox& rBounds ) SAL_OVERRIDE
666 : {
667 4594481 : if( drawMode == DrawMode_XOR )
668 115135 : implFillPolyPolygon( rPoly, fillColor,
669 : maBegin,
670 : maRawXorAccessor,
671 115135 : rBounds );
672 : else
673 4479346 : implFillPolyPolygon( rPoly, fillColor,
674 : maBegin,
675 : maRawAccessor,
676 4479346 : rBounds );
677 4594481 : }
678 :
679 61436 : virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
680 : Color fillColor,
681 : DrawMode drawMode,
682 : const basegfx::B2IBox& rBounds,
683 : const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
684 : {
685 61436 : if( drawMode == DrawMode_XOR )
686 186 : implFillPolyPolygon( rPoly, fillColor,
687 : getMaskedIter(rClip),
688 : maRawMaskedXorAccessor,
689 372 : rBounds );
690 : else
691 61250 : implFillPolyPolygon( rPoly, fillColor,
692 : getMaskedIter(rClip),
693 : maRawMaskedAccessor,
694 122500 : rBounds );
695 61436 : }
696 :
697 : template< typename Iterator, typename RawAcc >
698 13002 : void implDrawBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
699 : const basegfx::B2IBox& rSrcRect,
700 : const basegfx::B2IBox& rDstRect,
701 : const Iterator& begin,
702 : const RawAcc& acc)
703 : {
704 13002 : boost::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
705 : OSL_ASSERT( pSrcBmp );
706 :
707 13002 : scaleImage(
708 13002 : srcIterRange(pSrcBmp->maBegin,
709 13002 : pSrcBmp->maRawAccessor,
710 26004 : rSrcRect),
711 : destIterRange(begin,
712 : acc,
713 : rDstRect),
714 39006 : isSharedBuffer(rSrcBitmap) );
715 13002 : damaged( rDstRect );
716 13002 : }
717 :
718 : template< typename Iterator, typename Acc >
719 3834 : void implDrawBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
720 : const basegfx::B2IBox& rSrcRect,
721 : const basegfx::B2IBox& rDstRect,
722 : const Iterator& begin,
723 : const Acc& acc)
724 : {
725 3834 : GenericColorImageAccessor aSrcAcc( rSrcBitmap );
726 :
727 3834 : scaleImage(
728 : srcIterRange(vigra::Diff2D(),
729 : aSrcAcc,
730 : rSrcRect),
731 : destIterRange(begin,
732 : acc,
733 7668 : rDstRect));
734 3834 : damaged( rDstRect );
735 3834 : }
736 :
737 565558 : void implDrawBitmapDirect(const BitmapDeviceSharedPtr& rSrcBitmap,
738 : const basegfx::B2IBox& rSrcRect,
739 : const basegfx::B2IBox& rDstRect)
740 : {
741 565558 : sal_Int32 nSrcX = rSrcRect.getMinX();
742 565558 : sal_Int32 nSrcY = rSrcRect.getMinY();
743 565558 : sal_Int32 nSrcWidth = rSrcRect.getWidth();
744 565558 : sal_Int32 nSrcHeight = rSrcRect.getHeight();
745 565558 : sal_Int32 nDestX = rDstRect.getMinX();
746 565558 : sal_Int32 nDestY = rDstRect.getMinY();
747 :
748 565558 : char* dstBuf = (char*)getBuffer().get();
749 565558 : char* srcBuf = (char*)rSrcBitmap->getBuffer().get();
750 565558 : sal_Int32 dstStride = getScanlineStride();
751 565558 : sal_Int32 srcStride = rSrcBitmap->getScanlineStride();
752 565558 : sal_Int32 bytesPerPixel = (bitsPerPixel[getScanlineFormat()] + 7) >> 3; // round up to bytes
753 565558 : bool dstTopDown = isTopDown();
754 565558 : bool srcTopDown = rSrcBitmap->isTopDown();
755 :
756 565558 : if (dstBuf == srcBuf && nSrcY < nDestY) // reverse copy order to avoid overlapping
757 : {
758 72 : nSrcY = getBufferSize().getY() - nSrcY - nSrcHeight;
759 72 : nDestY = getBufferSize().getY() - nDestY - nSrcHeight;
760 72 : srcTopDown = !srcTopDown;
761 72 : dstTopDown = !dstTopDown;
762 : }
763 :
764 565558 : if (!dstTopDown)
765 : {
766 565484 : dstBuf += dstStride * (getBufferSize().getY() - 1);
767 565484 : dstStride = -dstStride;
768 : }
769 :
770 565558 : if (!srcTopDown)
771 : {
772 565484 : srcBuf += srcStride * (rSrcBitmap->getBufferSize().getY() - 1);
773 565484 : srcStride = -srcStride;
774 : }
775 :
776 565558 : char* dstline = dstBuf + dstStride * nDestY + nDestX * bytesPerPixel;
777 565558 : char* srcline = srcBuf + srcStride * nSrcY + nSrcX * bytesPerPixel;
778 565558 : sal_Int32 lineBytes = nSrcWidth * bytesPerPixel;
779 :
780 33395771 : for(; 0 < nSrcHeight; nSrcHeight--)
781 : {
782 32830213 : memmove(dstline, srcline, lineBytes);
783 32830213 : dstline += dstStride;
784 32830213 : srcline += srcStride;
785 : }
786 565558 : }
787 :
788 580355 : virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
789 : const basegfx::B2IBox& rSrcRect,
790 : const basegfx::B2IBox& rDstRect,
791 : DrawMode drawMode ) SAL_OVERRIDE
792 : {
793 580355 : if( isCompatibleBitmap( rSrcBitmap ) )
794 : {
795 576521 : if( drawMode == DrawMode_XOR )
796 0 : implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
797 : maBegin,
798 0 : maRawXorAccessor);
799 2273241 : else if (bitsPerPixel[getScanlineFormat()] >= 8
800 1131162 : && rSrcRect.getWidth() == rDstRect.getWidth() && rSrcRect.getHeight() == rDstRect.getHeight()
801 565558 : && rSrcBitmap->getScanlineFormat() == getScanlineFormat())
802 565558 : implDrawBitmapDirect(rSrcBitmap, rSrcRect, rDstRect);
803 : else
804 10963 : implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
805 : maBegin,
806 10963 : maRawAccessor);
807 : }
808 : else
809 : {
810 3834 : if( drawMode == DrawMode_XOR )
811 0 : implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
812 : maBegin,
813 0 : maXorAccessor);
814 : else
815 3834 : implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
816 : maBegin,
817 3834 : maAccessor);
818 : }
819 580355 : damaged( rDstRect );
820 580355 : }
821 :
822 2039 : virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
823 : const basegfx::B2IBox& rSrcRect,
824 : const basegfx::B2IBox& rDstRect,
825 : DrawMode drawMode,
826 : const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
827 : {
828 2039 : if( isCompatibleBitmap( rSrcBitmap ) )
829 : {
830 2039 : if( drawMode == DrawMode_XOR )
831 0 : implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
832 : getMaskedIter(rClip),
833 0 : maRawMaskedXorAccessor);
834 : else
835 2039 : implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
836 : getMaskedIter(rClip),
837 4078 : maRawMaskedAccessor);
838 : }
839 : else
840 : {
841 0 : if( drawMode == DrawMode_XOR )
842 0 : implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
843 : getMaskedIter(rClip),
844 0 : maMaskedXorAccessor);
845 : else
846 0 : implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect,
847 : getMaskedIter(rClip),
848 0 : maMaskedAccessor);
849 : }
850 2039 : damaged( rDstRect );
851 2039 : }
852 :
853 2292933 : virtual void drawMaskedColor_i(Color aSrcColor,
854 : const BitmapDeviceSharedPtr& rAlphaMask,
855 : const basegfx::B2IBox& rSrcRect,
856 : const basegfx::B2IPoint& rDstPoint ) SAL_OVERRIDE
857 : {
858 2292933 : boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rAlphaMask) );
859 4585866 : boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
860 :
861 2292933 : if( pAlpha )
862 : {
863 2292933 : maColorBlendAccessor.setColor( aSrcColor );
864 :
865 4585866 : vigra::copyImage( srcIterRange(pAlpha->maBegin,
866 2292933 : pAlpha->maRawAccessor,
867 : rSrcRect),
868 : destIter(maBegin,
869 : maColorBlendAccessor,
870 6878799 : rDstPoint) );
871 : }
872 0 : else if( pMask )
873 : {
874 : const composite_iterator_type aBegin(
875 0 : maBegin + vigra::Diff2D(rDstPoint.getX(),
876 : rDstPoint.getY()),
877 0 : pMask->maBegin + topLeft(rSrcRect) );
878 :
879 0 : fillImage(aBegin,
880 0 : aBegin + vigra::Diff2D(rSrcRect.getWidth(),
881 0 : rSrcRect.getHeight()),
882 : maRawMaskedAccessor,
883 : maColorLookup(
884 : maAccessor,
885 0 : aSrcColor) );
886 : }
887 : else
888 : {
889 0 : GenericColorImageAccessor aSrcAcc( rAlphaMask );
890 0 : maGenericColorBlendAccessor.setColor( aSrcColor );
891 :
892 0 : vigra::copyImage( srcIterRange(vigra::Diff2D(),
893 : aSrcAcc,
894 : rSrcRect),
895 : destIter(maBegin,
896 : maGenericColorBlendAccessor,
897 0 : rDstPoint) );
898 : }
899 4585866 : damagedPointSize( rDstPoint, rSrcRect );
900 2292933 : }
901 :
902 725 : virtual void drawMaskedColor_i(Color aSrcColor,
903 : const BitmapDeviceSharedPtr& rAlphaMask,
904 : const basegfx::B2IBox& rSrcRect,
905 : const basegfx::B2IPoint& rDstPoint,
906 : const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
907 : {
908 725 : boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rAlphaMask) );
909 1450 : boost::shared_ptr<alphamask_bitmap_type> pAlpha( getCompatibleAlphaMask(rAlphaMask) );
910 :
911 725 : if( pAlpha )
912 : {
913 725 : const composite_iterator_type aBegin( getMaskedIter(rClip) );
914 725 : maMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
915 : aSrcColor );
916 :
917 1450 : vigra::copyImage( srcIterRange(pAlpha->maBegin,
918 725 : pAlpha->maRawAccessor,
919 : rSrcRect),
920 : destIter(aBegin,
921 : maMaskedColorBlendAccessor,
922 2900 : rDstPoint) );
923 : }
924 0 : else if( pMask )
925 : {
926 0 : boost::shared_ptr<mask_bitmap_type> pClipMask( getCompatibleClipMask(rClip) );
927 : OSL_ASSERT( pClipMask );
928 :
929 : // setup a ((iter,mask),clipMask) composite composite
930 : // iterator, to pass both masks (clip and alpha mask)
931 : // to the algorithm
932 : const composite_composite_mask_iterator_type aBegin(
933 : composite_iterator_type(
934 0 : maBegin + vigra::Diff2D(rDstPoint.getX(),
935 : rDstPoint.getY()),
936 0 : pMask->maBegin + topLeft(rSrcRect)),
937 0 : pClipMask->maBegin + vigra::Diff2D(rDstPoint.getX(),
938 0 : rDstPoint.getY()) );
939 :
940 0 : fillImage(aBegin,
941 0 : aBegin + vigra::Diff2D(rSrcRect.getWidth(),
942 0 : rSrcRect.getHeight()),
943 : maRawMaskedMaskAccessor,
944 : maColorLookup(
945 : maAccessor,
946 0 : aSrcColor) );
947 : }
948 : else
949 : {
950 0 : GenericColorImageAccessor aSrcAcc( rAlphaMask );
951 0 : const composite_iterator_type aBegin( getMaskedIter(rClip) );
952 0 : maGenericMaskedColorBlendAccessor.get1stWrappedAccessor().setColor(
953 : aSrcColor );
954 :
955 0 : vigra::copyImage( srcIterRange(vigra::Diff2D(),
956 : aSrcAcc,
957 : rSrcRect),
958 : destIter(aBegin,
959 : maGenericMaskedColorBlendAccessor,
960 0 : rDstPoint) );
961 : }
962 1450 : damagedPointSize( rDstPoint, rSrcRect );
963 725 : }
964 :
965 : template< typename Iterator, typename Acc >
966 8 : void implDrawMaskedBitmap(const BitmapDeviceSharedPtr& rSrcBitmap,
967 : const BitmapDeviceSharedPtr& rMask,
968 : const basegfx::B2IBox& rSrcRect,
969 : const basegfx::B2IBox& rDstRect,
970 : const Iterator& begin,
971 : const Acc& acc)
972 : {
973 8 : boost::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) );
974 16 : boost::shared_ptr<mask_bitmap_type> pMask( getCompatibleClipMask(rMask) );
975 : OSL_ASSERT( pMask && pSrcBmp );
976 :
977 8 : scaleImage(
978 : srcIterRange(composite_iterator_type(
979 8 : pSrcBmp->maBegin,
980 8 : pMask->maBegin),
981 : joined_image_accessor_type(
982 8 : pSrcBmp->maAccessor,
983 8 : pMask->maRawAccessor),
984 : rSrcRect),
985 : destIterRange(begin,
986 : typename masked_input_splitting_accessor<
987 : Acc,
988 : joined_image_accessor_type,
989 : Masks::clipmask_polarity,
990 : FastMask >::type(acc),
991 16 : rDstRect),
992 48 : isSharedBuffer(rSrcBitmap));
993 16 : damaged( rDstRect );
994 8 : }
995 :
996 : template< typename Iterator, typename Acc >
997 19315 : void implDrawMaskedBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap,
998 : const BitmapDeviceSharedPtr& rMask,
999 : const basegfx::B2IBox& rSrcRect,
1000 : const basegfx::B2IBox& rDstRect,
1001 : const Iterator& begin,
1002 : const Acc& acc)
1003 : {
1004 19315 : GenericColorImageAccessor aSrcAcc( rSrcBitmap );
1005 38630 : GenericColorImageAccessor aMaskAcc( rMask );
1006 :
1007 : const vigra::Diff2D aTopLeft(rSrcRect.getMinX(),
1008 19315 : rSrcRect.getMinY());
1009 : const vigra::Diff2D aBottomRight(rSrcRect.getMaxX(),
1010 19315 : rSrcRect.getMaxY());
1011 19315 : scaleImage(
1012 : vigra::make_triple(
1013 : generic_composite_iterator_type(
1014 : aTopLeft,aTopLeft),
1015 : generic_composite_iterator_type(
1016 : aBottomRight,aBottomRight),
1017 : joined_generic_image_accessor_type(
1018 : aSrcAcc,
1019 : aMaskAcc)),
1020 : destIterRange(begin,
1021 : typename masked_input_splitting_accessor<
1022 : Acc,
1023 : joined_generic_image_accessor_type,
1024 : Masks::clipmask_polarity,
1025 : NoFastMask >::type(acc),
1026 38630 : rDstRect));
1027 38630 : damaged( rDstRect );
1028 19315 : }
1029 :
1030 19321 : virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
1031 : const BitmapDeviceSharedPtr& rMask,
1032 : const basegfx::B2IBox& rSrcRect,
1033 : const basegfx::B2IBox& rDstRect,
1034 : DrawMode drawMode ) SAL_OVERRIDE
1035 : {
1036 19329 : if( isCompatibleClipMask(rMask) &&
1037 8 : isCompatibleBitmap(rSrcBitmap) )
1038 : {
1039 8 : if( drawMode == DrawMode_XOR )
1040 0 : implDrawMaskedBitmap(rSrcBitmap, rMask,
1041 : rSrcRect, rDstRect,
1042 : maBegin,
1043 0 : maXorAccessor);
1044 : else
1045 8 : implDrawMaskedBitmap(rSrcBitmap, rMask,
1046 : rSrcRect, rDstRect,
1047 : maBegin,
1048 8 : maAccessor);
1049 : }
1050 : else
1051 : {
1052 19313 : if( drawMode == DrawMode_XOR )
1053 0 : implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
1054 : rSrcRect, rDstRect,
1055 : maBegin,
1056 0 : maXorAccessor);
1057 : else
1058 19313 : implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
1059 : rSrcRect, rDstRect,
1060 : maBegin,
1061 19313 : maAccessor);
1062 : }
1063 19321 : damaged( rDstRect );
1064 19321 : }
1065 :
1066 2 : virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
1067 : const BitmapDeviceSharedPtr& rMask,
1068 : const basegfx::B2IBox& rSrcRect,
1069 : const basegfx::B2IBox& rDstRect,
1070 : DrawMode drawMode,
1071 : const BitmapDeviceSharedPtr& rClip ) SAL_OVERRIDE
1072 : {
1073 2 : if( isCompatibleClipMask(rMask) &&
1074 0 : isCompatibleBitmap(rSrcBitmap) )
1075 : {
1076 0 : if( drawMode == DrawMode_XOR )
1077 0 : implDrawMaskedBitmap(rSrcBitmap, rMask,
1078 : rSrcRect, rDstRect,
1079 : getMaskedIter(rClip),
1080 0 : maMaskedXorAccessor);
1081 : else
1082 0 : implDrawMaskedBitmap(rSrcBitmap, rMask,
1083 : rSrcRect, rDstRect,
1084 : getMaskedIter(rClip),
1085 0 : maMaskedAccessor);
1086 : }
1087 : else
1088 : {
1089 2 : if( drawMode == DrawMode_XOR )
1090 0 : implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
1091 : rSrcRect, rDstRect,
1092 : getMaskedIter(rClip),
1093 0 : maMaskedXorAccessor);
1094 : else
1095 2 : implDrawMaskedBitmapGeneric(rSrcBitmap, rMask,
1096 : rSrcRect, rDstRect,
1097 : getMaskedIter(rClip),
1098 4 : maMaskedAccessor);
1099 : }
1100 2 : damaged( rDstRect );
1101 2 : }
1102 :
1103 1256252 : IBitmapDeviceDamageTrackerSharedPtr getDamageTracker_i() const SAL_OVERRIDE
1104 : {
1105 1256252 : return mpDamage;
1106 : }
1107 0 : void setDamageTracker_i( const IBitmapDeviceDamageTrackerSharedPtr& rDamage ) SAL_OVERRIDE
1108 : {
1109 0 : mpDamage = rDamage;
1110 0 : }
1111 : };
1112 : } // namespace
1113 :
1114 3637015 : struct ImplBitmapDevice
1115 : {
1116 : /** Bitmap memory plus deleter.
1117 :
1118 : Always points to the start of the mem
1119 : */
1120 : RawMemorySharedArray mpMem;
1121 :
1122 : /// Palette memory plus deleter (might be NULL)
1123 : PaletteMemorySharedVector mpPalette;
1124 :
1125 : /** Bounds of the device.
1126 :
1127 : maBounds.getWidth()/getHeight() yield the true size of the
1128 : device (i.e. the rectangle given by maBounds covers the device
1129 : area under the including-the-bottommost-and-rightmost-pixels
1130 : fill rule)
1131 : */
1132 : basegfx::B2IBox maBounds;
1133 :
1134 : //// Size of the actual frame buffer
1135 : basegfx::B2IVector maBufferSize;
1136 :
1137 : /// Scanline format, as provided at the constructor
1138 : Format mnScanlineFormat;
1139 :
1140 : /// Scanline stride. Negative for bottom-to-top formats
1141 : sal_Int32 mnScanlineStride;
1142 :
1143 : /// raw ptr to 0th scanline. used for cloning a generic renderer
1144 : sal_uInt8* mpFirstScanline;
1145 :
1146 : /** (Optional) device sharing the same memory, and used for input
1147 : clip masks/alpha masks/bitmaps that don't match our exact
1148 : bitmap format.
1149 :
1150 : This is to avoid the combinatorical explosion when dealing
1151 : with n bitmap formats, which could be combined with n clip
1152 : masks, alpha masks and bitmap masks (yielding a total of n^4
1153 : combinations). Since each BitmapRenderer is specialized for
1154 : one specific combination of said formats, a lot of duplicate
1155 : code would be generated, most of which probably never
1156 : used. Therefore, only the most common combinations are
1157 : specialized templates, the remainder gets handled by this
1158 : generic renderer (via runtime polymorphism).
1159 : */
1160 : BitmapDeviceSharedPtr mpGenericRenderer;
1161 : };
1162 :
1163 :
1164 1830472 : BitmapDevice::BitmapDevice( const basegfx::B2IBox& rBounds,
1165 : const basegfx::B2IVector& rBufferSize,
1166 : Format nScanlineFormat,
1167 : sal_Int32 nScanlineStride,
1168 : sal_uInt8* pFirstScanline,
1169 : const RawMemorySharedArray& rMem,
1170 : const PaletteMemorySharedVector& rPalette ) :
1171 1830472 : mpImpl( new ImplBitmapDevice )
1172 : {
1173 1830472 : mpImpl->mpMem = rMem;
1174 1830472 : mpImpl->mpPalette = rPalette;
1175 1830472 : mpImpl->maBounds = rBounds;
1176 1830472 : mpImpl->maBufferSize = rBufferSize;
1177 1830472 : mpImpl->mnScanlineFormat = nScanlineFormat;
1178 1830472 : mpImpl->mnScanlineStride = nScanlineStride;
1179 1830472 : mpImpl->mpFirstScanline = pFirstScanline;
1180 1830472 : }
1181 :
1182 1806543 : BitmapDevice::~BitmapDevice()
1183 : {
1184 : // outline, because of internal ImplBitmapDevice
1185 : SAL_INFO( "basebmp.bitmapdevice", "~BitmapDevice(" << this << ")" );
1186 1806543 : }
1187 :
1188 15537538 : basegfx::B2IVector BitmapDevice::getSize() const
1189 : {
1190 : return basegfx::B2IVector(
1191 15537538 : mpImpl->maBounds.getMaxX() - mpImpl->maBounds.getMinX(),
1192 31075076 : mpImpl->maBounds.getMaxY() - mpImpl->maBounds.getMinY() );
1193 : }
1194 :
1195 3699346 : bool BitmapDevice::isTopDown() const
1196 : {
1197 3699346 : return mpImpl->mnScanlineStride >= 0;
1198 : }
1199 :
1200 1131112 : basegfx::B2IVector BitmapDevice::getBufferSize() const
1201 : {
1202 1131112 : return mpImpl->maBufferSize;
1203 : }
1204 :
1205 10442003 : Format BitmapDevice::getScanlineFormat() const
1206 : {
1207 10442003 : return mpImpl->mnScanlineFormat;
1208 : }
1209 :
1210 2299378 : sal_Int32 BitmapDevice::getScanlineStride() const
1211 : {
1212 2299378 : return mpImpl->mnScanlineStride < 0 ?
1213 2299378 : -mpImpl->mnScanlineStride : mpImpl->mnScanlineStride;
1214 : }
1215 :
1216 8019921 : RawMemorySharedArray BitmapDevice::getBuffer() const
1217 : {
1218 8019921 : return mpImpl->mpMem;
1219 : }
1220 :
1221 1256252 : IBitmapDeviceDamageTrackerSharedPtr BitmapDevice::getDamageTracker() const
1222 : {
1223 1256252 : return getDamageTracker_i();
1224 : }
1225 :
1226 0 : void BitmapDevice::setDamageTracker( const IBitmapDeviceDamageTrackerSharedPtr& rDamage )
1227 : {
1228 0 : setDamageTracker_i(rDamage);
1229 0 : }
1230 :
1231 2022779 : PaletteMemorySharedVector BitmapDevice::getPalette() const
1232 : {
1233 2022779 : return mpImpl->mpPalette;
1234 : }
1235 :
1236 2306668 : bool BitmapDevice::isSharedBuffer( const BitmapDeviceSharedPtr& rOther ) const
1237 : {
1238 2306668 : return rOther.get()->getBuffer().get() == getBuffer().get();
1239 : }
1240 :
1241 148 : void BitmapDevice::clear( Color fillColor )
1242 : {
1243 148 : clear_i( fillColor, mpImpl->maBounds );
1244 148 : }
1245 :
1246 782184 : void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
1247 : Color lineColor,
1248 : DrawMode drawMode )
1249 : {
1250 782184 : if( mpImpl->maBounds.isInside(rPt) )
1251 768243 : setPixel_i(rPt,lineColor,drawMode);
1252 782184 : }
1253 :
1254 1340091 : void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
1255 : Color lineColor,
1256 : DrawMode drawMode,
1257 : const BitmapDeviceSharedPtr& rClip )
1258 : {
1259 1340091 : if( !rClip )
1260 : {
1261 782124 : setPixel(rPt,lineColor,drawMode);
1262 2122215 : return;
1263 : }
1264 :
1265 557967 : if( mpImpl->maBounds.isInside(rPt) )
1266 : {
1267 557967 : if( isCompatibleClipMask( rClip ) )
1268 557967 : setPixel_i(rPt,lineColor,drawMode,rClip);
1269 : else
1270 0 : getGenericRenderer()->setPixel( rPt, lineColor, drawMode, rClip );
1271 : }
1272 : }
1273 :
1274 123542882 : Color BitmapDevice::getPixel( const basegfx::B2IPoint& rPt )
1275 : {
1276 123542882 : if( mpImpl->maBounds.isInside(rPt) )
1277 123542882 : return getPixel_i(rPt);
1278 :
1279 0 : return Color();
1280 : }
1281 :
1282 12 : sal_uInt32 BitmapDevice::getPixelData( const basegfx::B2IPoint& rPt )
1283 : {
1284 12 : if( mpImpl->maBounds.isInside(rPt) )
1285 8 : return getPixelData_i(rPt);
1286 :
1287 4 : return 0;
1288 : }
1289 :
1290 3244323 : void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
1291 : const basegfx::B2IPoint& rPt2,
1292 : Color lineColor,
1293 : DrawMode drawMode )
1294 : {
1295 : drawLine_i( rPt1,
1296 : rPt2,
1297 3244323 : mpImpl->maBounds,
1298 : lineColor,
1299 6488646 : drawMode );
1300 3244323 : }
1301 :
1302 3330181 : void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
1303 : const basegfx::B2IPoint& rPt2,
1304 : Color lineColor,
1305 : DrawMode drawMode,
1306 : const BitmapDeviceSharedPtr& rClip )
1307 : {
1308 3330181 : if( !rClip )
1309 : {
1310 3244271 : drawLine(rPt1,rPt2,lineColor,drawMode);
1311 6574452 : return;
1312 : }
1313 :
1314 85910 : if( isCompatibleClipMask( rClip ) )
1315 : drawLine_i( rPt1,
1316 : rPt2,
1317 85910 : mpImpl->maBounds,
1318 : lineColor,
1319 : drawMode,
1320 171820 : rClip );
1321 : else
1322 : getGenericRenderer()->drawLine( rPt1, rPt2, lineColor,
1323 0 : drawMode, rClip );
1324 : }
1325 :
1326 261264 : void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
1327 : Color lineColor,
1328 : DrawMode drawMode )
1329 : {
1330 261264 : const sal_uInt32 numVertices( rPoly.count() );
1331 261264 : if( numVertices )
1332 : drawPolygon_i( rPoly,
1333 261264 : mpImpl->maBounds,
1334 522528 : lineColor, drawMode );
1335 261264 : }
1336 :
1337 262740 : void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
1338 : Color lineColor,
1339 : DrawMode drawMode,
1340 : const BitmapDeviceSharedPtr& rClip )
1341 : {
1342 262740 : if( !rClip )
1343 : {
1344 261230 : drawPolygon(rPoly,lineColor,drawMode);
1345 523970 : return;
1346 : }
1347 :
1348 1510 : const sal_uInt32 numVertices( rPoly.count() );
1349 1510 : if( numVertices )
1350 : {
1351 1510 : if( isCompatibleClipMask( rClip ) )
1352 : drawPolygon_i( rPoly,
1353 1510 : mpImpl->maBounds,
1354 3020 : lineColor, drawMode, rClip );
1355 : else
1356 : getGenericRenderer()->drawPolygon( rPoly, lineColor,
1357 0 : drawMode, rClip );
1358 : }
1359 : }
1360 :
1361 4594481 : void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
1362 : Color fillColor,
1363 : DrawMode drawMode )
1364 : {
1365 4594481 : fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds );
1366 4594481 : }
1367 :
1368 4549114 : void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
1369 : Color fillColor,
1370 : DrawMode drawMode,
1371 : const BitmapDeviceSharedPtr& rClip )
1372 : {
1373 4549114 : if( !rClip )
1374 : {
1375 4487678 : fillPolyPolygon(rPoly,fillColor,drawMode);
1376 9036792 : return;
1377 : }
1378 :
1379 61436 : if( isCompatibleClipMask( rClip ) )
1380 61436 : fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds, rClip );
1381 : else
1382 : getGenericRenderer()->fillPolyPolygon( rPoly, fillColor,
1383 0 : drawMode, rClip );
1384 : }
1385 :
1386 :
1387 : namespace
1388 : {
1389 2293658 : void assertImagePoint( const basegfx::B2IPoint& rPt,
1390 : const basegfx::B2IBox& rPermittedRange )
1391 : {
1392 : (void)rPt; (void)rPermittedRange;
1393 : OSL_ASSERT( rPermittedRange.isInside(rPt) );
1394 2293658 : }
1395 :
1396 3497092 : void assertImageRange( const basegfx::B2IBox& rRange,
1397 : const basegfx::B2IBox& rPermittedRange )
1398 : {
1399 : #if OSL_DEBUG_LEVEL > 0
1400 : basegfx::B2IBox aRange( rRange );
1401 : aRange.intersect( rPermittedRange );
1402 :
1403 : OSL_ASSERT( aRange == rRange );
1404 : #else
1405 : (void)rRange; (void)rPermittedRange;
1406 : #endif
1407 3497092 : }
1408 :
1409 : // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1410 : // to basegfx, and use here!
1411 3274133 : bool clipAreaImpl( ::basegfx::B2IBox& io_rSourceArea,
1412 : ::basegfx::B2IPoint& io_rDestPoint,
1413 : const ::basegfx::B2IBox& rSourceBounds,
1414 : const ::basegfx::B2IBox& rDestBounds )
1415 : {
1416 : const ::basegfx::B2IPoint aSourceTopLeft(
1417 3274133 : io_rSourceArea.getMinimum() );
1418 :
1419 3274133 : ::basegfx::B2IBox aLocalSourceArea( io_rSourceArea );
1420 :
1421 : // clip source area (which must be inside rSourceBounds)
1422 3274133 : aLocalSourceArea.intersect( rSourceBounds );
1423 :
1424 3274133 : if( aLocalSourceArea.isEmpty() )
1425 0 : return false;
1426 :
1427 : // calc relative new source area points (relative to orig
1428 : // source area)
1429 : const ::basegfx::B2IVector aUpperLeftOffset(
1430 6548266 : aLocalSourceArea.getMinimum()-aSourceTopLeft );
1431 : const ::basegfx::B2IVector aLowerRightOffset(
1432 6548266 : aLocalSourceArea.getMaximum()-aSourceTopLeft );
1433 :
1434 6548266 : ::basegfx::B2IBox aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
1435 9822399 : io_rDestPoint + aLowerRightOffset );
1436 :
1437 : // clip dest area (which must be inside rDestBounds)
1438 3274133 : aLocalDestArea.intersect( rDestBounds );
1439 :
1440 3274133 : if( aLocalDestArea.isEmpty() )
1441 980475 : return false;
1442 :
1443 : // calc relative new dest area points (relative to orig
1444 : // source area)
1445 : const ::basegfx::B2IVector aDestUpperLeftOffset(
1446 4587316 : aLocalDestArea.getMinimum()-io_rDestPoint );
1447 : const ::basegfx::B2IVector aDestLowerRightOffset(
1448 4587316 : aLocalDestArea.getMaximum()-io_rDestPoint );
1449 :
1450 4587316 : io_rSourceArea = ::basegfx::B2IBox( aSourceTopLeft + aDestUpperLeftOffset,
1451 6880974 : aSourceTopLeft + aDestLowerRightOffset );
1452 2293658 : io_rDestPoint = aLocalDestArea.getMinimum();
1453 :
1454 5567791 : return true;
1455 : }
1456 :
1457 : // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
1458 : // to basegfx, and use here!
1459 602696 : bool clipAreaImpl( ::basegfx::B2IBox& io_rDestArea,
1460 : ::basegfx::B2IBox& io_rSourceArea,
1461 : const ::basegfx::B2IBox& rDestBounds,
1462 : const ::basegfx::B2IBox& rSourceBounds )
1463 : {
1464 : // extract inherent scale
1465 602696 : double fWidth = io_rSourceArea.getWidth();
1466 602696 : if (fWidth == 0.0)
1467 0 : return false;
1468 :
1469 602696 : double fHeight = io_rSourceArea.getHeight();
1470 602696 : if (fHeight == 0.0)
1471 0 : return false;
1472 :
1473 602696 : const double nScaleX( io_rDestArea.getWidth() / fWidth );
1474 602696 : const double nScaleY( io_rDestArea.getHeight() / fHeight );
1475 :
1476 : // extract range origins
1477 : const basegfx::B2IPoint aDestTopLeft(
1478 602696 : io_rDestArea.getMinimum() );
1479 : const ::basegfx::B2IPoint aSourceTopLeft(
1480 1205392 : io_rSourceArea.getMinimum() );
1481 :
1482 602696 : ::basegfx::B2IBox aLocalSourceArea( io_rSourceArea );
1483 :
1484 : // clip source area (which must be inside rSourceBounds)
1485 602696 : aLocalSourceArea.intersect( rSourceBounds );
1486 :
1487 602696 : if( aLocalSourceArea.isEmpty() )
1488 16 : return false;
1489 :
1490 : // calc relative new source area points (relative to orig
1491 : // source area)
1492 : const ::basegfx::B2IVector aUpperLeftOffset(
1493 1205360 : aLocalSourceArea.getMinimum()-aSourceTopLeft );
1494 : const ::basegfx::B2IVector aLowerRightOffset(
1495 1205360 : aLocalSourceArea.getMaximum()-aSourceTopLeft );
1496 :
1497 1205360 : ::basegfx::B2IBox aLocalDestArea( basegfx::fround(aDestTopLeft.getX() + nScaleX*aUpperLeftOffset.getX()),
1498 1205360 : basegfx::fround(aDestTopLeft.getY() + nScaleY*aUpperLeftOffset.getY()),
1499 1205360 : basegfx::fround(aDestTopLeft.getX() + nScaleX*aLowerRightOffset.getX()),
1500 4218760 : basegfx::fround(aDestTopLeft.getY() + nScaleY*aLowerRightOffset.getY()) );
1501 :
1502 : // clip dest area (which must be inside rDestBounds)
1503 602680 : aLocalDestArea.intersect( rDestBounds );
1504 :
1505 602680 : if( aLocalDestArea.isEmpty() )
1506 963 : return false;
1507 :
1508 : // calc relative new dest area points (relative to orig
1509 : // source area)
1510 : const ::basegfx::B2IVector aDestUpperLeftOffset(
1511 1203434 : aLocalDestArea.getMinimum()-aDestTopLeft );
1512 : const ::basegfx::B2IVector aDestLowerRightOffset(
1513 1203434 : aLocalDestArea.getMaximum()-aDestTopLeft );
1514 :
1515 1203434 : io_rSourceArea = ::basegfx::B2IBox( basegfx::fround(aSourceTopLeft.getX() + aDestUpperLeftOffset.getX()/nScaleX),
1516 1203434 : basegfx::fround(aSourceTopLeft.getY() + aDestUpperLeftOffset.getY()/nScaleY),
1517 1203434 : basegfx::fround(aSourceTopLeft.getX() + aDestLowerRightOffset.getX()/nScaleX),
1518 4212019 : basegfx::fround(aSourceTopLeft.getY() + aDestLowerRightOffset.getY()/nScaleY) );
1519 601717 : io_rDestArea = aLocalDestArea;
1520 :
1521 : // final source area clip (chopping round-offs)
1522 601717 : io_rSourceArea.intersect( rSourceBounds );
1523 :
1524 601717 : if( io_rSourceArea.isEmpty() )
1525 0 : return false;
1526 :
1527 :
1528 1204413 : return true;
1529 : }
1530 : }
1531 :
1532 581334 : void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1533 : const basegfx::B2IBox& rSrcRect,
1534 : const basegfx::B2IBox& rDstRect,
1535 : DrawMode drawMode )
1536 : {
1537 581334 : const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1538 581334 : const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1539 581334 : basegfx::B2IBox aSrcRange( rSrcRect );
1540 581334 : basegfx::B2IBox aDestRange( rDstRect );
1541 :
1542 581334 : if( clipAreaImpl( aDestRange,
1543 : aSrcRange,
1544 581334 : mpImpl->maBounds,
1545 581334 : aSrcBounds ))
1546 : {
1547 580355 : assertImageRange(aDestRange,mpImpl->maBounds);
1548 580355 : assertImageRange(aSrcRange,aSrcBounds);
1549 :
1550 580355 : drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode );
1551 581334 : }
1552 581334 : }
1553 :
1554 304985 : void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1555 : const basegfx::B2IBox& rSrcRect,
1556 : const basegfx::B2IBox& rDstRect,
1557 : DrawMode drawMode,
1558 : const BitmapDeviceSharedPtr& rClip )
1559 : {
1560 304985 : if( !rClip )
1561 : {
1562 302946 : drawBitmap(rSrcBitmap,rSrcRect,rDstRect,drawMode);
1563 607931 : return;
1564 : }
1565 :
1566 2039 : const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1567 2039 : const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1568 2039 : basegfx::B2IBox aSrcRange( rSrcRect );
1569 2039 : basegfx::B2IBox aDestRange( rDstRect );
1570 :
1571 2039 : if( clipAreaImpl( aDestRange,
1572 : aSrcRange,
1573 2039 : mpImpl->maBounds,
1574 2039 : aSrcBounds ))
1575 : {
1576 2039 : assertImageRange(aDestRange,mpImpl->maBounds);
1577 2039 : assertImageRange(aSrcRange,aSrcBounds);
1578 :
1579 2039 : if( isCompatibleClipMask( rClip ) )
1580 : {
1581 2039 : drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode, rClip );
1582 : }
1583 : else
1584 : {
1585 : getGenericRenderer()->drawBitmap( rSrcBitmap, rSrcRect,
1586 0 : rDstRect, drawMode, rClip );
1587 : }
1588 2039 : }
1589 : }
1590 :
1591 3273336 : void BitmapDevice::drawMaskedColor( Color aSrcColor,
1592 : const BitmapDeviceSharedPtr& rAlphaMask,
1593 : const basegfx::B2IBox& rSrcRect,
1594 : const basegfx::B2IPoint& rDstPoint )
1595 : {
1596 3273336 : const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
1597 3273336 : const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1598 3273336 : basegfx::B2IBox aSrcRange( rSrcRect );
1599 6546672 : basegfx::B2IPoint aDestPoint( rDstPoint );
1600 :
1601 3273336 : if( clipAreaImpl( aSrcRange,
1602 : aDestPoint,
1603 : aSrcBounds,
1604 3273336 : mpImpl->maBounds ))
1605 : {
1606 2292933 : assertImagePoint(aDestPoint,mpImpl->maBounds);
1607 2292933 : assertImageRange(aSrcRange,aSrcBounds);
1608 :
1609 2292933 : if( isSharedBuffer(rAlphaMask) )
1610 : {
1611 : // src == dest, copy rAlphaMask beforehand
1612 :
1613 :
1614 0 : const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
1615 0 : aSrcRange.getHeight() );
1616 : BitmapDeviceSharedPtr pAlphaCopy(
1617 : cloneBitmapDevice( aSize,
1618 0 : shared_from_this()) );
1619 : const basegfx::B2IBox aAlphaRange( basegfx::B2ITuple(),
1620 0 : aSize );
1621 : pAlphaCopy->drawBitmap(rAlphaMask,
1622 : aSrcRange,
1623 : aAlphaRange,
1624 0 : DrawMode_PAINT);
1625 0 : drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint );
1626 : }
1627 : else
1628 : {
1629 2292933 : drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint );
1630 : }
1631 3273336 : }
1632 3273336 : }
1633 :
1634 3274117 : void BitmapDevice::drawMaskedColor( Color aSrcColor,
1635 : const BitmapDeviceSharedPtr& rAlphaMask,
1636 : const basegfx::B2IBox& rSrcRect,
1637 : const basegfx::B2IPoint& rDstPoint,
1638 : const BitmapDeviceSharedPtr& rClip )
1639 : {
1640 3274117 : if( !rClip )
1641 : {
1642 3273320 : drawMaskedColor(aSrcColor,rAlphaMask,rSrcRect,rDstPoint);
1643 6547437 : return;
1644 : }
1645 :
1646 797 : const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
1647 797 : const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1648 797 : basegfx::B2IBox aSrcRange( rSrcRect );
1649 1594 : basegfx::B2IPoint aDestPoint( rDstPoint );
1650 :
1651 797 : if( clipAreaImpl( aSrcRange,
1652 : aDestPoint,
1653 : aSrcBounds,
1654 797 : mpImpl->maBounds ))
1655 : {
1656 725 : assertImagePoint(aDestPoint,mpImpl->maBounds);
1657 725 : assertImageRange(aSrcRange,aSrcBounds);
1658 :
1659 725 : if( isCompatibleClipMask( rClip ) )
1660 : {
1661 725 : if( isSharedBuffer(rAlphaMask) )
1662 : {
1663 : // src == dest, copy rAlphaMask beforehand
1664 :
1665 :
1666 0 : const basegfx::B2ITuple aSize( aSrcRange.getWidth(),
1667 0 : aSrcRange.getHeight() );
1668 : BitmapDeviceSharedPtr pAlphaCopy(
1669 : cloneBitmapDevice( aSize,
1670 0 : shared_from_this()) );
1671 : const basegfx::B2IBox aAlphaRange( basegfx::B2ITuple(),
1672 0 : aSize );
1673 : pAlphaCopy->drawBitmap(rAlphaMask,
1674 : aSrcRange,
1675 : aAlphaRange,
1676 0 : DrawMode_PAINT);
1677 0 : drawMaskedColor_i( aSrcColor, pAlphaCopy, aAlphaRange, aDestPoint, rClip );
1678 : }
1679 : else
1680 : {
1681 725 : drawMaskedColor_i( aSrcColor, rAlphaMask, aSrcRange, aDestPoint, rClip );
1682 : }
1683 : }
1684 : else
1685 : {
1686 : getGenericRenderer()->drawMaskedColor( aSrcColor, rAlphaMask,
1687 0 : rSrcRect, rDstPoint, rClip );
1688 : }
1689 797 : }
1690 : }
1691 :
1692 19321 : void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1693 : const BitmapDeviceSharedPtr& rMask,
1694 : const basegfx::B2IBox& rSrcRect,
1695 : const basegfx::B2IBox& rDstRect,
1696 : DrawMode drawMode )
1697 : {
1698 : OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
1699 :
1700 19321 : const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1701 19321 : const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1702 19321 : basegfx::B2IBox aSrcRange( rSrcRect );
1703 19321 : basegfx::B2IBox aDestRange( rDstRect );
1704 :
1705 19321 : if( clipAreaImpl( aDestRange,
1706 : aSrcRange,
1707 19321 : mpImpl->maBounds,
1708 19321 : aSrcBounds ))
1709 : {
1710 19321 : assertImageRange(aDestRange,mpImpl->maBounds);
1711 19321 : assertImageRange(aSrcRange,aSrcBounds);
1712 :
1713 19321 : drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode );
1714 19321 : }
1715 19321 : }
1716 :
1717 19315 : void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
1718 : const BitmapDeviceSharedPtr& rMask,
1719 : const basegfx::B2IBox& rSrcRect,
1720 : const basegfx::B2IBox& rDstRect,
1721 : DrawMode drawMode,
1722 : const BitmapDeviceSharedPtr& rClip )
1723 : {
1724 19315 : if( !rClip )
1725 : {
1726 19313 : drawMaskedBitmap(rSrcBitmap,rMask,rSrcRect,rDstRect,drawMode);
1727 38628 : return;
1728 : }
1729 :
1730 : OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
1731 :
1732 2 : const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
1733 2 : const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
1734 2 : basegfx::B2IBox aSrcRange( rSrcRect );
1735 2 : basegfx::B2IBox aDestRange( rDstRect );
1736 :
1737 2 : if( clipAreaImpl( aDestRange,
1738 : aSrcRange,
1739 2 : mpImpl->maBounds,
1740 2 : aSrcBounds ))
1741 : {
1742 2 : assertImageRange(aDestRange,mpImpl->maBounds);
1743 2 : assertImageRange(aSrcRange,aSrcBounds);
1744 :
1745 2 : if( isCompatibleClipMask( rClip ) )
1746 : {
1747 2 : drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode, rClip );
1748 : }
1749 : else
1750 : {
1751 : getGenericRenderer()->drawMaskedBitmap( rSrcBitmap, rMask, rSrcRect,
1752 0 : rDstRect, drawMode, rClip );
1753 : }
1754 2 : }
1755 : }
1756 :
1757 :
1758 :
1759 : /** Standard clip and alpha masks
1760 : */
1761 : struct StdMasks
1762 : {
1763 : typedef PixelFormatTraits_GREY1_MSB clipmask_format_traits;
1764 : typedef PixelFormatTraits_GREY8 alphamask_format_traits;
1765 :
1766 : /// Clipmask: 0 means opaque
1767 : static const bool clipmask_polarity = false;
1768 :
1769 : /// Alpha mask: 0 means fully transparent
1770 : static const bool alphamask_polarity = true;
1771 : };
1772 :
1773 :
1774 : // Some compilers don't like the nested template wrap_accessor
1775 : // reference in the parameter list - being slightly less type safe,
1776 : // then.
1777 : #ifndef BASEBMP_NO_NESTED_TEMPLATE_PARAMETER
1778 :
1779 : /// Produces a specialized renderer for the given pixel format
1780 : template< class FormatTraits, class MaskTraits >
1781 1830472 : BitmapDeviceSharedPtr createRenderer(
1782 : const basegfx::B2IBox& rBounds,
1783 : const basegfx::B2IVector& rBufferSize,
1784 : Format nScanlineFormat,
1785 : sal_Int32 nScanlineStride,
1786 : sal_uInt8* pFirstScanline,
1787 : typename FormatTraits::raw_accessor_type const& rRawAccessor,
1788 : typename FormatTraits::accessor_selector::template wrap_accessor<
1789 : typename FormatTraits::raw_accessor_type>::type const& rAccessor,
1790 : boost::shared_array< sal_uInt8 > pMem,
1791 : const PaletteMemorySharedVector& pPal,
1792 : const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
1793 : #else
1794 :
1795 : template< class FormatTraits, class MaskTraits, class Accessor >
1796 : BitmapDeviceSharedPtr createRenderer(
1797 : const basegfx::B2IBox& rBounds,
1798 : const basegfx::B2IVector& rBufferSize,
1799 : Format nScanlineFormat,
1800 : sal_Int32 nScanlineStride,
1801 : sal_uInt8* pFirstScanline,
1802 : typename FormatTraits::raw_accessor_type const& rRawAccessor,
1803 : Accessor const& rAccessor,
1804 : boost::shared_array< sal_uInt8 > pMem,
1805 : const PaletteMemorySharedVector& pPal,
1806 : const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
1807 :
1808 : #endif
1809 : {
1810 : typedef typename FormatTraits::iterator_type Iterator;
1811 : typedef BitmapRenderer< Iterator,
1812 : typename FormatTraits::raw_accessor_type,
1813 : typename FormatTraits::accessor_selector,
1814 : MaskTraits > Renderer;
1815 :
1816 : return BitmapDeviceSharedPtr(
1817 : new Renderer( rBounds,
1818 : rBufferSize,
1819 : nScanlineFormat,
1820 : nScanlineStride,
1821 : pFirstScanline,
1822 : Iterator(
1823 : reinterpret_cast<typename Iterator::value_type*>(
1824 : pFirstScanline),
1825 : nScanlineStride),
1826 : rRawAccessor,
1827 : rAccessor,
1828 : pMem,
1829 : pPal,
1830 1830472 : pDamage ));
1831 : }
1832 :
1833 : /// Create standard grey level palette
1834 294322 : PaletteMemorySharedVector createStandardPalette(
1835 : const PaletteMemorySharedVector& pPal,
1836 : sal_Int32 nNumEntries )
1837 : {
1838 294322 : if( pPal || nNumEntries <= 0 )
1839 294250 : return pPal;
1840 :
1841 : boost::shared_ptr< std::vector<Color> > pLocalPal(
1842 72 : new std::vector<Color>(nNumEntries) );
1843 :
1844 72 : const sal_Int32 nIncrement( 0x00FFFFFF/nNumEntries );
1845 72 : --nNumEntries;
1846 144 : for( sal_Int32 i=0, c=0; i<nNumEntries; ++i,c+=nIncrement )
1847 72 : pLocalPal->at(i) = Color(0xFF000000 | c);
1848 :
1849 72 : pLocalPal->at(nNumEntries) = Color(0xFFFFFFFF);
1850 :
1851 72 : return pLocalPal;
1852 : }
1853 :
1854 : template< class FormatTraits, class MaskTraits >
1855 1536150 : BitmapDeviceSharedPtr createRenderer(
1856 : const basegfx::B2IBox& rBounds,
1857 : const basegfx::B2IVector& rBufferSize,
1858 : Format nScanlineFormat,
1859 : sal_Int32 nScanlineStride,
1860 : sal_uInt8* pFirstScanline,
1861 : boost::shared_array< sal_uInt8 > pMem,
1862 : const PaletteMemorySharedVector& pPal,
1863 : const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
1864 : {
1865 : return createRenderer<FormatTraits,
1866 : MaskTraits>(rBounds,
1867 : rBufferSize,
1868 : nScanlineFormat,
1869 : nScanlineStride,
1870 : pFirstScanline,
1871 : typename FormatTraits::raw_accessor_type(),
1872 : typename FormatTraits::accessor_selector::template
1873 : wrap_accessor<
1874 : typename FormatTraits::raw_accessor_type>::type(),
1875 : pMem,
1876 : pPal,
1877 1536150 : pDamage);
1878 : }
1879 :
1880 : template< class FormatTraits, class MaskTraits >
1881 294322 : BitmapDeviceSharedPtr createRenderer(
1882 : const basegfx::B2IBox& rBounds,
1883 : const basegfx::B2IVector& rBufferSize,
1884 : Format nScanlineFormat,
1885 : sal_Int32 nScanlineStride,
1886 : sal_uInt8* pFirstScanline,
1887 : boost::shared_array< sal_uInt8 > pMem,
1888 : PaletteMemorySharedVector pPal,
1889 : int nBitsPerPixel,
1890 : const IBitmapDeviceDamageTrackerSharedPtr& pDamage )
1891 : {
1892 294322 : pPal = createStandardPalette(pPal,
1893 : 1UL << nBitsPerPixel);
1894 :
1895 : OSL_ASSERT(pPal);
1896 : return createRenderer<FormatTraits,
1897 : MaskTraits>(rBounds,
1898 : rBufferSize,
1899 : nScanlineFormat,
1900 : nScanlineStride,
1901 : pFirstScanline,
1902 : typename FormatTraits::raw_accessor_type(),
1903 : typename FormatTraits::accessor_selector::template
1904 : wrap_accessor<
1905 : typename FormatTraits::raw_accessor_type>::type(
1906 294322 : &pPal->at(0),
1907 : pPal->size()),
1908 : pMem,
1909 : pPal,
1910 588644 : pDamage);
1911 : }
1912 :
1913 :
1914 : // TODO(Q3): consolidate with canvas/canvastools.hxx! Best move this
1915 : // to o3tl or sal/bithacks.hxx ...
1916 :
1917 : /** Compute the next highest power of 2 of a 32-bit value
1918 :
1919 : Code devised by Sean Anderson, in good ole HAKMEM
1920 : tradition.
1921 :
1922 : @return 1 << (lg(x - 1) + 1)
1923 : */
1924 1830478 : inline sal_uInt32 nextPow2( sal_uInt32 x )
1925 : {
1926 1830478 : --x;
1927 1830478 : x |= x >> 1;
1928 1830478 : x |= x >> 2;
1929 1830478 : x |= x >> 4;
1930 1830478 : x |= x >> 8;
1931 1830478 : x |= x >> 16;
1932 :
1933 1830478 : return ++x;
1934 : }
1935 :
1936 :
1937 :
1938 :
1939 : namespace
1940 : {
1941 1830478 : BitmapDeviceSharedPtr createBitmapDeviceImplInner( const basegfx::B2IVector& rSize,
1942 : bool bTopDown,
1943 : Format nScanlineFormat,
1944 : boost::shared_array< sal_uInt8 > pMem,
1945 : PaletteMemorySharedVector pPal,
1946 : const basegfx::B2IBox* pSubset,
1947 : const IBitmapDeviceDamageTrackerSharedPtr& rDamage,
1948 : bool bBlack = true)
1949 : {
1950 : OSL_ASSERT(rSize.getX() > 0 && rSize.getY() > 0);
1951 :
1952 3660956 : if( nScanlineFormat <= FORMAT_NONE ||
1953 1830478 : nScanlineFormat > FORMAT_MAX )
1954 0 : return BitmapDeviceSharedPtr();
1955 :
1956 1830478 : sal_uInt8 nBitsPerPixel = bitsPerPixel[nScanlineFormat];
1957 1830478 : if (rSize.getX() > (SAL_MAX_INT32-7) / nBitsPerPixel)
1958 : {
1959 : SAL_WARN("basebmp", "suspicious bitmap width " <<
1960 : rSize.getX() << " for depth " << nBitsPerPixel);
1961 0 : return BitmapDeviceSharedPtr();
1962 : }
1963 : // round up to full 8 bit, divide by 8
1964 1830478 : sal_Int32 nScanlineStride = (rSize.getX()*nBitsPerPixel + 7) >> 3;
1965 :
1966 : // rounded up to next full power-of-two number of bytes
1967 : const sal_uInt32 bytesPerPixel = nextPow2(
1968 1830478 : (bitsPerPixel[nScanlineFormat] + 7) >> 3);
1969 :
1970 : // now make nScanlineStride a multiple of bytesPerPixel
1971 1830478 : nScanlineStride = (nScanlineStride + bytesPerPixel - 1) / bytesPerPixel * bytesPerPixel;
1972 :
1973 : // factor in bottom-up scanline order case
1974 1830478 : nScanlineStride *= bTopDown ? 1 : -1;
1975 :
1976 1830478 : const sal_uInt32 nWidth(nScanlineStride < 0 ? -nScanlineStride : nScanlineStride);
1977 1830478 : const sal_uInt32 nHeight(rSize.getY());
1978 :
1979 1830478 : if (nHeight && nWidth && nWidth > SAL_MAX_INT32 / nHeight)
1980 : {
1981 : SAL_WARN( "basebmp", "suspicious massive alloc " << nWidth << " * " << nHeight);
1982 6 : return BitmapDeviceSharedPtr();
1983 : }
1984 :
1985 1830472 : const std::size_t nMemSize(nWidth * nHeight);
1986 :
1987 1830472 : if( !pMem )
1988 : {
1989 : pMem.reset(
1990 700879 : reinterpret_cast<sal_uInt8*>(rtl_allocateMemory( nMemSize )),
1991 700879 : &rtl_freeMemory );
1992 700879 : if (pMem.get() == 0 && nMemSize != 0)
1993 0 : return BitmapDeviceSharedPtr();
1994 700879 : if (bBlack)
1995 672864 : memset(pMem.get(), 0, nMemSize);
1996 : else
1997 28015 : memset(pMem.get(), 0xFF, nMemSize);
1998 : }
1999 :
2000 : sal_uInt8* pFirstScanline = nScanlineStride < 0 ?
2001 1830472 : pMem.get() + nMemSize + nScanlineStride : pMem.get();
2002 :
2003 : // shrink render area to given subset, if given
2004 1830472 : basegfx::B2IBox aBounds(0,0,rSize.getX(),rSize.getY());
2005 1830472 : if( pSubset )
2006 963481 : aBounds.intersect( *pSubset );
2007 :
2008 1830472 : switch( nScanlineFormat )
2009 : {
2010 :
2011 : // one bit formats
2012 :
2013 : case FORMAT_ONE_BIT_MSB_GREY:
2014 : return createRenderer<PixelFormatTraits_GREY1_MSB,StdMasks>(
2015 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2016 28029 : pFirstScanline, pMem, pPal, rDamage );
2017 :
2018 : case FORMAT_ONE_BIT_LSB_GREY:
2019 : return createRenderer<PixelFormatTraits_GREY1_LSB,StdMasks>(
2020 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2021 0 : pFirstScanline, pMem, pPal, rDamage );
2022 :
2023 : case FORMAT_ONE_BIT_MSB_PAL:
2024 : return createRenderer<PixelFormatTraits_PAL1_MSB,StdMasks>(
2025 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2026 : pFirstScanline, pMem, pPal,
2027 35598 : bitsPerPixel[nScanlineFormat], rDamage );
2028 :
2029 : case FORMAT_ONE_BIT_LSB_PAL:
2030 : return createRenderer<PixelFormatTraits_PAL1_LSB,StdMasks>(
2031 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2032 : pFirstScanline, pMem, pPal,
2033 2 : bitsPerPixel[nScanlineFormat], rDamage );
2034 :
2035 :
2036 :
2037 : // four bit formats
2038 :
2039 : case FORMAT_FOUR_BIT_MSB_GREY:
2040 : return createRenderer<PixelFormatTraits_GREY4_MSB,StdMasks>(
2041 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2042 0 : pFirstScanline, pMem, pPal, rDamage );
2043 :
2044 : case FORMAT_FOUR_BIT_LSB_GREY:
2045 : return createRenderer<PixelFormatTraits_GREY4_LSB,StdMasks>(
2046 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2047 0 : pFirstScanline, pMem, pPal, rDamage );
2048 :
2049 : case FORMAT_FOUR_BIT_MSB_PAL:
2050 : return createRenderer<PixelFormatTraits_PAL4_MSB,StdMasks>(
2051 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2052 : pFirstScanline, pMem, pPal,
2053 526 : bitsPerPixel[nScanlineFormat], rDamage );
2054 :
2055 : case FORMAT_FOUR_BIT_LSB_PAL:
2056 : return createRenderer<PixelFormatTraits_PAL4_LSB,StdMasks>(
2057 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2058 : pFirstScanline, pMem, pPal,
2059 0 : bitsPerPixel[nScanlineFormat], rDamage );
2060 :
2061 :
2062 :
2063 : // eight bit formats
2064 :
2065 : case FORMAT_EIGHT_BIT_GREY:
2066 : return createRenderer<PixelFormatTraits_GREY8,StdMasks>(
2067 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2068 22406 : pFirstScanline, pMem, pPal, rDamage );
2069 :
2070 : case FORMAT_EIGHT_BIT_PAL:
2071 : return createRenderer<PixelFormatTraits_PAL8,StdMasks>(
2072 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2073 : pFirstScanline, pMem, pPal,
2074 258196 : bitsPerPixel[nScanlineFormat], rDamage );
2075 :
2076 :
2077 :
2078 : // sixteen bit formats
2079 :
2080 : case FORMAT_SIXTEEN_BIT_LSB_TC_MASK:
2081 : return createRenderer<PixelFormatTraits_RGB16_565_LSB,StdMasks>(
2082 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2083 4 : pFirstScanline, pMem, pPal, rDamage );
2084 :
2085 : case FORMAT_SIXTEEN_BIT_MSB_TC_MASK:
2086 : return createRenderer<PixelFormatTraits_RGB16_565_MSB,StdMasks>(
2087 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2088 0 : pFirstScanline, pMem, pPal, rDamage );
2089 :
2090 :
2091 :
2092 : // twentyfour bit formats
2093 : case FORMAT_TWENTYFOUR_BIT_TC_MASK:
2094 : return createRenderer<PixelFormatTraits_BGR24,StdMasks>(
2095 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2096 1485639 : pFirstScanline, pMem, pPal, rDamage );
2097 :
2098 :
2099 :
2100 : // thirtytwo bit formats
2101 :
2102 : case FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA:
2103 : return createRenderer<PixelFormatTraits_BGRX32_8888,StdMasks>(
2104 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2105 72 : pFirstScanline, pMem, pPal, rDamage );
2106 :
2107 : case FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB:
2108 : return createRenderer<PixelFormatTraits_XRGB32_8888,StdMasks>(
2109 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2110 0 : pFirstScanline, pMem, pPal, rDamage );
2111 :
2112 : case FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR:
2113 : return createRenderer<PixelFormatTraits_XBGR32_8888,StdMasks>(
2114 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2115 0 : pFirstScanline, pMem, pPal, rDamage );
2116 :
2117 : case FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA:
2118 : return createRenderer<PixelFormatTraits_RGBX32_8888,StdMasks>(
2119 : aBounds, rSize, nScanlineFormat, nScanlineStride,
2120 0 : pFirstScanline, pMem, pPal, rDamage );
2121 :
2122 : default:
2123 : assert(false); // this cannot happen
2124 : }
2125 :
2126 : // TODO(F3): other formats not yet implemented
2127 0 : return BitmapDeviceSharedPtr();
2128 : }
2129 :
2130 1830478 : BitmapDeviceSharedPtr createBitmapDeviceImpl( const basegfx::B2IVector& rSize,
2131 : bool bTopDown,
2132 : Format nScanlineFormat,
2133 : boost::shared_array< sal_uInt8 > pMem,
2134 : PaletteMemorySharedVector pPal,
2135 : const basegfx::B2IBox* pSubset,
2136 : const IBitmapDeviceDamageTrackerSharedPtr& rDamage,
2137 : bool bBlack = true)
2138 : {
2139 1830478 : BitmapDeviceSharedPtr result( createBitmapDeviceImplInner( rSize, bTopDown, nScanlineFormat, pMem, pPal, pSubset, rDamage, bBlack ) );
2140 :
2141 : #ifdef SAL_LOG_INFO
2142 : std::ostringstream subset;
2143 :
2144 : if (pSubset)
2145 : subset << " subset=" << pSubset->getWidth() << "x" << pSubset->getHeight() << "@(" << pSubset->getMinX() << "," << pSubset->getMinY() << ")";
2146 :
2147 : SAL_INFO( "basebmp.bitmapdevice",
2148 : "createBitmapDevice: "
2149 : << rSize.getX() << "x" << rSize.getY()
2150 : << (bTopDown ? " top-down " : " bottom-up ")
2151 : << formatName(nScanlineFormat)
2152 : << subset.str()
2153 : << " = " << result.get() );
2154 : #endif
2155 1830478 : return result;
2156 : }
2157 : } // namespace
2158 :
2159 :
2160 274534 : BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
2161 : bool bTopDown,
2162 : Format nScanlineFormat )
2163 : {
2164 : return createBitmapDeviceImpl( rSize,
2165 : bTopDown,
2166 : nScanlineFormat,
2167 : boost::shared_array< sal_uInt8 >(),
2168 : PaletteMemorySharedVector(),
2169 : NULL,
2170 274534 : IBitmapDeviceDamageTrackerSharedPtr() );
2171 : }
2172 :
2173 20668 : BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
2174 : bool bTopDown,
2175 : Format nScanlineFormat,
2176 : const PaletteMemorySharedVector& rPalette )
2177 : {
2178 : return createBitmapDeviceImpl( rSize,
2179 : bTopDown,
2180 : nScanlineFormat,
2181 : boost::shared_array< sal_uInt8 >(),
2182 : rPalette,
2183 : NULL,
2184 20668 : IBitmapDeviceDamageTrackerSharedPtr() );
2185 : }
2186 :
2187 251009 : BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
2188 : bool bTopDown,
2189 : Format nScanlineFormat,
2190 : const RawMemorySharedArray& rMem,
2191 : const PaletteMemorySharedVector& rPalette )
2192 : {
2193 : return createBitmapDeviceImpl( rSize,
2194 : bTopDown,
2195 : nScanlineFormat,
2196 : rMem,
2197 : rPalette,
2198 : NULL,
2199 251009 : IBitmapDeviceDamageTrackerSharedPtr() );
2200 : }
2201 :
2202 28015 : BitmapDeviceSharedPtr createClipDevice( const basegfx::B2IVector& rSize )
2203 : {
2204 : BitmapDeviceSharedPtr xClip(
2205 : createBitmapDeviceImpl( rSize,
2206 : false, /* bTopDown */
2207 : basebmp::FORMAT_ONE_BIT_MSB_GREY,
2208 : boost::shared_array< sal_uInt8 >(),
2209 : PaletteMemorySharedVector(),
2210 : NULL,
2211 : IBitmapDeviceDamageTrackerSharedPtr(),
2212 28015 : false /* white */) );
2213 28015 : return xClip;
2214 : }
2215 :
2216 963481 : BitmapDeviceSharedPtr subsetBitmapDevice( const BitmapDeviceSharedPtr& rProto,
2217 : const basegfx::B2IBox& rSubset )
2218 : {
2219 : SAL_INFO( "basebmp.bitmapdevice", "subsetBitmapDevice: proto=" << rProto.get() );
2220 : return createBitmapDeviceImpl( rProto->getSize(),
2221 963481 : rProto->isTopDown(),
2222 : rProto->getScanlineFormat(),
2223 : rProto->getBuffer(),
2224 : rProto->getPalette(),
2225 : &rSubset,
2226 1926962 : rProto->getDamageTracker() );
2227 : }
2228 :
2229 292771 : BitmapDeviceSharedPtr cloneBitmapDevice( const basegfx::B2IVector& rSize,
2230 : const BitmapDeviceSharedPtr& rProto )
2231 : {
2232 : return createBitmapDeviceImpl( rSize,
2233 292771 : rProto->isTopDown(),
2234 : rProto->getScanlineFormat(),
2235 : boost::shared_array< sal_uInt8 >(),
2236 : rProto->getPalette(),
2237 : NULL,
2238 585542 : rProto->getDamageTracker() );
2239 : }
2240 :
2241 :
2242 : /// Clone our device, with GenericImageAccessor to handle all formats
2243 0 : BitmapDeviceSharedPtr BitmapDevice::getGenericRenderer() const
2244 : {
2245 0 : return mpImpl->mpGenericRenderer;
2246 : }
2247 :
2248 : } // namespace basebmp
2249 :
2250 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|