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