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