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