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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_drawinglayer.hxx" 26 27 #include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx> 28 #include <drawinglayer/animation/animationtiming.hxx> 29 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 30 #include <drawinglayer/primitive2d/animatedprimitive2d.hxx> 31 #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> 32 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 33 #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 34 #include <basegfx/polygon/b2dpolygon.hxx> 35 #include <basegfx/polygon/b2dpolygontools.hxx> 36 37 ////////////////////////////////////////////////////////////////////////////// 38 // helper class for animated graphics 39 40 #include <vcl/animate.hxx> 41 #include <vcl/graph.hxx> 42 #include <vcl/virdev.hxx> 43 #include <vcl/svapp.hxx> 44 #include <vcl/metaact.hxx> 45 46 ////////////////////////////////////////////////////////////////////////////// 47 // includes for testing MetafilePrimitive2D::create2DDecomposition 48 49 // this switch defines if the test code is included or not 50 #undef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 51 52 #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 53 #include <vcl/gradient.hxx> 54 #include <vcl/pngread.hxx> 55 #include <vcl/lineinfo.hxx> 56 #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 57 58 ////////////////////////////////////////////////////////////////////////////// 59 60 namespace 61 { 62 struct animationStep 63 { 64 BitmapEx maBitmapEx; 65 sal_uInt32 mnTime; 66 }; 67 68 class animatedBitmapExPreparator 69 { 70 ::Animation maAnimation; 71 ::std::vector< animationStep > maSteps; 72 73 sal_uInt32 generateStepTime(sal_uInt32 nIndex) const; 74 75 public: 76 animatedBitmapExPreparator(const Graphic& rGraphic); 77 78 sal_uInt32 count() const { return maSteps.size(); } 79 sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); } 80 sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; } 81 const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; } 82 }; 83 84 sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const 85 { 86 const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex)); 87 sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10); 88 89 // #115934# 90 // Take care of special value for MultiPage TIFFs. ATM these shall just 91 // show their first page. Later we will offer some switching when object 92 // is selected. 93 if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait) 94 { 95 // ATM the huge value would block the timer, so 96 // use a long time to show first page (whole day) 97 nWaitTime = 100 * 60 * 60 * 24; 98 } 99 100 // Bad trap: There are animated gifs with no set WaitTime (!). 101 // In that case use a default value. 102 if(0L == nWaitTime) 103 { 104 nWaitTime = 100L; 105 } 106 107 return nWaitTime; 108 } 109 110 animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic) 111 : maAnimation(rGraphic.GetAnimation()) 112 { 113 OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)"); 114 115 // #128539# secure access to Animation, looks like there exist animated GIFs out there 116 // with a step count of zero 117 if(maAnimation.Count()) 118 { 119 VirtualDevice aVirtualDevice(*Application::GetDefaultDevice()); 120 VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L); 121 122 // Prepare VirtualDevices and their states 123 aVirtualDevice.EnableMapMode(sal_False); 124 aVirtualDeviceMask.EnableMapMode(sal_False); 125 aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel()); 126 aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel()); 127 aVirtualDevice.Erase(); 128 aVirtualDeviceMask.Erase(); 129 130 for(sal_uInt16 a(0L); a < maAnimation.Count(); a++) 131 { 132 animationStep aNextStep; 133 aNextStep.mnTime = generateStepTime(a); 134 135 // prepare step 136 const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a)); 137 138 switch(rAnimBitmap.eDisposal) 139 { 140 case DISPOSE_NOT: 141 { 142 aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); 143 Bitmap aMask = rAnimBitmap.aBmpEx.GetMask(); 144 145 if(aMask.IsEmpty()) 146 { 147 const Point aEmpty; 148 const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel()); 149 const Wallpaper aWallpaper(COL_BLACK); 150 aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper); 151 } 152 else 153 { 154 BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask); 155 aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask); 156 } 157 158 break; 159 } 160 case DISPOSE_BACK: 161 { 162 // #i70772# react on no mask, for primitives, too. 163 const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask()); 164 const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap()); 165 166 aVirtualDeviceMask.Erase(); 167 aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent); 168 169 if(aMask.IsEmpty()) 170 { 171 const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel()); 172 aVirtualDeviceMask.SetFillColor(COL_BLACK); 173 aVirtualDeviceMask.SetLineColor(); 174 aVirtualDeviceMask.DrawRect(aRect); 175 } 176 else 177 { 178 aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask); 179 } 180 181 break; 182 } 183 case DISPOSE_FULL: 184 { 185 aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); 186 break; 187 } 188 case DISPOSE_PREVIOUS : 189 { 190 aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); 191 aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask()); 192 break; 193 } 194 } 195 196 // create BitmapEx 197 Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel()); 198 Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap(Point(), aVirtualDeviceMask.GetOutputSizePixel()); 199 aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap); 200 201 // add to vector 202 maSteps.push_back(aNextStep); 203 } 204 } 205 } 206 } // end of anonymous namespace 207 208 ////////////////////////////////////////////////////////////////////////////// 209 210 namespace drawinglayer 211 { 212 namespace primitive2d 213 { 214 Primitive2DSequence create2DDecompositionOfGraphic( 215 const Graphic& rGraphic, 216 const basegfx::B2DHomMatrix& rTransform) 217 { 218 Primitive2DSequence aRetval; 219 220 switch(rGraphic.GetType()) 221 { 222 case GRAPHIC_BITMAP : 223 { 224 if(rGraphic.IsAnimated()) 225 { 226 // prepare animation data 227 animatedBitmapExPreparator aData(rGraphic); 228 229 if(aData.count()) 230 { 231 // create sub-primitives for animated bitmap and the needed animation loop 232 animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff); 233 Primitive2DSequence aBitmapPrimitives(aData.count()); 234 235 for(sal_uInt32 a(0); a < aData.count(); a++) 236 { 237 animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count()); 238 aAnimationLoop.append(aTime); 239 aBitmapPrimitives[a] = new BitmapPrimitive2D( 240 aData.stepBitmapEx(a), 241 rTransform); 242 } 243 244 // prepare animation list 245 animation::AnimationEntryList aAnimationList; 246 aAnimationList.append(aAnimationLoop); 247 248 // create and add animated switch primitive 249 aRetval.realloc(1); 250 aRetval[0] = new AnimatedSwitchPrimitive2D( 251 aAnimationList, 252 aBitmapPrimitives, 253 false); 254 } 255 } 256 else if(rGraphic.getSvgData().get()) 257 { 258 // embedded Svg fill, create embed transform 259 const basegfx::B2DRange& rSvgRange(rGraphic.getSvgData()->getRange()); 260 261 if(basegfx::fTools::more(rSvgRange.getWidth(), 0.0) && basegfx::fTools::more(rSvgRange.getHeight(), 0.0)) 262 { 263 // translate back to origin, scale to unit coordinates 264 basegfx::B2DHomMatrix aEmbedSvg( 265 basegfx::tools::createTranslateB2DHomMatrix( 266 -rSvgRange.getMinX(), 267 -rSvgRange.getMinY())); 268 269 aEmbedSvg.scale( 270 1.0 / rSvgRange.getWidth(), 271 1.0 / rSvgRange.getHeight()); 272 273 // apply created object transformation 274 aEmbedSvg = rTransform * aEmbedSvg; 275 276 // add Svg primitives embedded 277 aRetval.realloc(1); 278 aRetval[0] = new TransformPrimitive2D( 279 aEmbedSvg, 280 rGraphic.getSvgData()->getPrimitive2DSequence()); 281 } 282 } 283 else 284 { 285 aRetval.realloc(1); 286 aRetval[0] = new BitmapPrimitive2D( 287 rGraphic.GetBitmapEx(), 288 rTransform); 289 } 290 291 break; 292 } 293 294 case GRAPHIC_GDIMETAFILE : 295 { 296 #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 297 static bool bDoTest(false); 298 299 if(bDoTest) 300 { 301 // All this is/was test code for testing MetafilePrimitive2D::create2DDecomposition 302 // extensively. It may be needed again when diverse actions need debugging, so i leave 303 // it in here, but take it out using USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE. 304 // Use it by compiling with the code, insert any DrawObject, convert to Metafile. The 305 // debugger will then stop here (when breakpoint set, of course). You may enter single 306 // parts of actions and/or change to true what You want to check. 307 GDIMetaFile aMtf; 308 VirtualDevice aOut; 309 const basegfx::B2DRange aRange(getB2DRange(rViewInformation)); 310 const Rectangle aRectangle( 311 basegfx::fround(aRange.getMinX()), basegfx::fround(aRange.getMinY()), 312 basegfx::fround(aRange.getMaxX()), basegfx::fround(aRange.getMaxY())); 313 const Point aOrigin(aRectangle.TopLeft()); 314 const Fraction aScaleX(aRectangle.getWidth()); 315 const Fraction aScaleY(aRectangle.getHeight()); 316 MapMode aMapMode(MAP_100TH_MM, aOrigin, aScaleX, aScaleY); 317 318 Size aDummySize(2, 2); 319 aOut.SetOutputSizePixel(aDummySize); 320 aOut.EnableOutput(FALSE); 321 aOut.SetMapMode(aMapMode); 322 323 aMtf.Clear(); 324 aMtf.Record(&aOut); 325 326 const Fraction aNeutralFraction(1, 1); 327 const MapMode aRelativeMapMode( 328 MAP_RELATIVE, 329 Point(-aRectangle.Left(), -aRectangle.Top()), 330 aNeutralFraction, aNeutralFraction); 331 aOut.SetMapMode(aRelativeMapMode); 332 333 if(false) 334 { 335 const sal_Int32 nHor(aRectangle.getWidth() / 4); 336 const sal_Int32 nVer(aRectangle.getHeight() / 4); 337 const Rectangle aCenteredRectangle( 338 aRectangle.Left() + nHor, aRectangle.Top() + nVer, 339 aRectangle.Right() - nHor, aRectangle.Bottom() - nVer); 340 aOut.SetClipRegion(aCenteredRectangle); 341 } 342 343 if(false) 344 { 345 const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight()); 346 aOut.IntersectClipRegion(aRightRectangle); 347 } 348 349 if(false) 350 { 351 const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight()); 352 const Rectangle aBottomRectangle(aRectangle.LeftCenter(), aRectangle.BottomRight()); 353 Region aRegion(aRightRectangle); 354 aRegion.Intersect(aBottomRectangle); 355 aOut.IntersectClipRegion(aRegion); 356 } 357 358 if(false) 359 { 360 const sal_Int32 nHor(aRectangle.getWidth() / 10); 361 const sal_Int32 nVer(aRectangle.getHeight() / 10); 362 aOut.MoveClipRegion(nHor, nVer); 363 } 364 365 if(false) 366 { 367 Wallpaper aWallpaper(Color(COL_BLACK)); 368 aOut.DrawWallpaper(aRectangle, aWallpaper); 369 } 370 371 if(false) 372 { 373 Wallpaper aWallpaper(Gradient(GRADIENT_LINEAR, Color(COL_RED), Color(COL_GREEN))); 374 aOut.DrawWallpaper(aRectangle, aWallpaper); 375 } 376 377 if(false) 378 { 379 SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); 380 vcl::PNGReader aPNGReader(aRead); 381 BitmapEx aBitmapEx(aPNGReader.Read()); 382 Wallpaper aWallpaper(aBitmapEx); 383 aOut.DrawWallpaper(aRectangle, aWallpaper); 384 } 385 386 if(false) 387 { 388 const double fHor(aRectangle.getWidth()); 389 const double fVer(aRectangle.getHeight()); 390 Color aColor(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)); 391 392 for(sal_uInt32 a(0); a < 5000; a++) 393 { 394 const Point aPoint( 395 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 396 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 397 398 if(!(a % 3)) 399 { 400 aColor = Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)); 401 } 402 403 aOut.DrawPixel(aPoint, aColor); 404 } 405 } 406 407 if(false) 408 { 409 const double fHor(aRectangle.getWidth()); 410 const double fVer(aRectangle.getHeight()); 411 412 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 413 aOut.SetFillColor(); 414 415 for(sal_uInt32 a(0); a < 5000; a++) 416 { 417 const Point aPoint( 418 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 419 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 420 aOut.DrawPixel(aPoint); 421 } 422 } 423 424 if(false) 425 { 426 const double fHor(aRectangle.getWidth()); 427 const double fVer(aRectangle.getHeight()); 428 429 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 430 aOut.SetFillColor(); 431 432 Point aStart( 433 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 434 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 435 Point aStop( 436 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 437 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 438 439 LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0)); 440 bool bUseLineInfo(false); 441 442 for(sal_uInt32 a(0); a < 20; a++) 443 { 444 if(!(a%6)) 445 { 446 bUseLineInfo = !bUseLineInfo; 447 } 448 449 if(!(a%4)) 450 { 451 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 452 } 453 454 if(a%3) 455 { 456 aStart = aStop; 457 aStop = Point( 458 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 459 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 460 } 461 else 462 { 463 aStart = Point( 464 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 465 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 466 aStop = Point( 467 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 468 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 469 } 470 471 if(bUseLineInfo) 472 { 473 aOut.DrawLine(aStart, aStop, aLineInfo); 474 } 475 else 476 { 477 aOut.DrawLine(aStart, aStop); 478 } 479 } 480 } 481 482 if(false) 483 { 484 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 485 aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 486 aOut.DrawRect(aRectangle); 487 } 488 489 if(false) 490 { 491 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 492 aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 493 const sal_uInt32 nHor(aRectangle.getWidth() / 10); 494 const sal_uInt32 nVer(aRectangle.getHeight() / 10); 495 aOut.DrawRect(aRectangle, nHor, nVer); 496 } 497 498 if(false) 499 { 500 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 501 aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 502 aOut.DrawEllipse(aRectangle); 503 } 504 505 if(false) 506 { 507 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 508 aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 509 aOut.DrawArc(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter()); 510 } 511 512 if(false) 513 { 514 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 515 aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 516 aOut.DrawPie(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter()); 517 } 518 519 if(false) 520 { 521 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 522 aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 523 aOut.DrawChord(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter()); 524 } 525 526 if(false) 527 { 528 const double fHor(aRectangle.getWidth()); 529 const double fVer(aRectangle.getHeight()); 530 531 for(sal_uInt32 b(0); b < 5; b++) 532 { 533 const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0))); 534 const bool bClose(basegfx::fround(rand() / 32767.0)); 535 Polygon aPolygon(nCount + (bClose ? 1 : 0)); 536 537 for(sal_uInt32 a(0); a < nCount; a++) 538 { 539 const Point aPoint( 540 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 541 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 542 aPolygon[a] = aPoint; 543 } 544 545 if(bClose) 546 { 547 aPolygon[aPolygon.GetSize() - 1] = aPolygon[0]; 548 } 549 550 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 551 aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 552 553 if(!(b%2)) 554 { 555 const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0)); 556 aOut.DrawPolyLine(aPolygon, aLineInfo); 557 } 558 else 559 { 560 aOut.DrawPolyLine(aPolygon); 561 } 562 } 563 } 564 565 if(false) 566 { 567 const double fHor(aRectangle.getWidth()); 568 const double fVer(aRectangle.getHeight()); 569 570 for(sal_uInt32 b(0); b < 5; b++) 571 { 572 const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0))); 573 const bool bClose(basegfx::fround(rand() / 32767.0)); 574 Polygon aPolygon(nCount + (bClose ? 1 : 0)); 575 576 for(sal_uInt32 a(0); a < nCount; a++) 577 { 578 const Point aPoint( 579 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 580 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 581 aPolygon[a] = aPoint; 582 } 583 584 if(bClose) 585 { 586 aPolygon[aPolygon.GetSize() - 1] = aPolygon[0]; 587 } 588 589 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 590 aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 591 aOut.DrawPolygon(aPolygon); 592 } 593 } 594 595 if(false) 596 { 597 const double fHor(aRectangle.getWidth()); 598 const double fVer(aRectangle.getHeight()); 599 PolyPolygon aPolyPolygon; 600 601 for(sal_uInt32 b(0); b < 3; b++) 602 { 603 const sal_uInt32 nCount(basegfx::fround(rand() * (6 / 32767.0))); 604 const bool bClose(basegfx::fround(rand() / 32767.0)); 605 Polygon aPolygon(nCount + (bClose ? 1 : 0)); 606 607 for(sal_uInt32 a(0); a < nCount; a++) 608 { 609 const Point aPoint( 610 aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 611 aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 612 aPolygon[a] = aPoint; 613 } 614 615 if(bClose) 616 { 617 aPolygon[aPolygon.GetSize() - 1] = aPolygon[0]; 618 } 619 620 aPolyPolygon.Insert(aPolygon); 621 } 622 623 aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 624 aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 625 aOut.DrawPolyPolygon(aPolyPolygon); 626 } 627 628 if(false) 629 { 630 SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); 631 vcl::PNGReader aPNGReader(aRead); 632 BitmapEx aBitmapEx(aPNGReader.Read()); 633 aOut.DrawBitmapEx(aRectangle.TopLeft(), aBitmapEx); 634 } 635 636 if(false) 637 { 638 SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); 639 vcl::PNGReader aPNGReader(aRead); 640 BitmapEx aBitmapEx(aPNGReader.Read()); 641 aOut.DrawBitmapEx(aRectangle.TopLeft(), aRectangle.GetSize(), aBitmapEx); 642 } 643 644 if(false) 645 { 646 SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); 647 vcl::PNGReader aPNGReader(aRead); 648 BitmapEx aBitmapEx(aPNGReader.Read()); 649 const Size aSizePixel(aBitmapEx.GetSizePixel()); 650 aOut.DrawBitmapEx( 651 aRectangle.TopLeft(), 652 aRectangle.GetSize(), 653 Point(0, 0), 654 Size(aSizePixel.Width() /2, aSizePixel.Height() / 2), 655 aBitmapEx); 656 } 657 658 if(false) 659 { 660 const double fHor(aRectangle.getWidth()); 661 const double fVer(aRectangle.getHeight()); 662 const Point aPointA( 663 aRectangle.Left() + basegfx::fround(fHor * 0.2), 664 aRectangle.Top() + basegfx::fround(fVer * 0.3)); 665 const Point aPointB( 666 aRectangle.Left() + basegfx::fround(fHor * 0.2), 667 aRectangle.Top() + basegfx::fround(fVer * 0.5)); 668 const Point aPointC( 669 aRectangle.Left() + basegfx::fround(fHor * 0.2), 670 aRectangle.Top() + basegfx::fround(fVer * 0.7)); 671 const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8); 672 673 const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8); 674 Font aFont(aFontName, Size(0, 1000)); 675 aFont.SetAlign(ALIGN_BASELINE); 676 aFont.SetColor(COL_RED); 677 //sal_Int32* pDXArray = new sal_Int32[aText.Len()]; 678 679 aFont.SetOutline(true); 680 aOut.SetFont(aFont); 681 aOut.DrawText(aPointA, aText, 0, aText.Len()); 682 683 aFont.SetShadow(true); 684 aOut.SetFont(aFont); 685 aOut.DrawText(aPointB, aText, 0, aText.Len()); 686 687 aFont.SetRelief(RELIEF_EMBOSSED); 688 aOut.SetFont(aFont); 689 aOut.DrawText(aPointC, aText, 0, aText.Len()); 690 691 //delete pDXArray; 692 } 693 694 if(false) 695 { 696 const double fHor(aRectangle.getWidth()); 697 const double fVer(aRectangle.getHeight()); 698 const Point aPointA( 699 aRectangle.Left() + basegfx::fround(fHor * 0.2), 700 aRectangle.Top() + basegfx::fround(fVer * 0.3)); 701 const Point aPointB( 702 aRectangle.Left() + basegfx::fround(fHor * 0.2), 703 aRectangle.Top() + basegfx::fround(fVer * 0.5)); 704 const Point aPointC( 705 aRectangle.Left() + basegfx::fround(fHor * 0.2), 706 aRectangle.Top() + basegfx::fround(fVer * 0.7)); 707 const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8); 708 709 const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8); 710 Font aFont(aFontName, Size(0, 1000)); 711 aFont.SetAlign(ALIGN_BASELINE); 712 aFont.SetColor(COL_RED); 713 714 aOut.SetFont(aFont); 715 const sal_Int32 nWidth(aOut.GetTextWidth(aText, 0, aText.Len())); 716 aOut.DrawText(aPointA, aText, 0, aText.Len()); 717 aOut.DrawTextLine(aPointA, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); 718 aOut.DrawTextLine(aPointB, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); 719 aOut.DrawTextLine(aPointC, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); 720 } 721 722 aMtf.Stop(); 723 aMtf.WindStart(); 724 aMtf.SetPrefMapMode(MapMode(MAP_100TH_MM)); 725 aMtf.SetPrefSize(Size(aRectangle.getWidth(), aRectangle.getHeight())); 726 727 aRetval.realloc(1); 728 aRetval[0] = new MetafilePrimitive2D( 729 rTransform, 730 aMtf); 731 } 732 else 733 { 734 #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 735 // create MetafilePrimitive2D 736 const GDIMetaFile& rMetafile = rGraphic.GetGDIMetaFile(); 737 738 aRetval.realloc(1); 739 aRetval[0] = new MetafilePrimitive2D( 740 rTransform, 741 rMetafile); 742 743 // #i100357# find out if clipping is needed for this primitive. Unfortunately, 744 // there exist Metafiles who's content is bigger than the proposed PrefSize set 745 // at them. This is an error, but we need to work around this 746 const Size aMetaFilePrefSize(rMetafile.GetPrefSize()); 747 const Size aMetaFileRealSize( 748 const_cast< GDIMetaFile& >(rMetafile).GetBoundRect( 749 *Application::GetDefaultDevice()).GetSize()); 750 751 if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth() 752 || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight()) 753 { 754 // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon 755 basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon()); 756 aMaskPolygon.transform(rTransform); 757 758 aRetval[0] = new MaskPrimitive2D( 759 basegfx::B2DPolyPolygon(aMaskPolygon), 760 aRetval); 761 } 762 #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 763 } 764 #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 765 766 break; 767 } 768 769 default: 770 { 771 // nothing to create 772 break; 773 } 774 } 775 776 return aRetval; 777 } 778 } // end of namespace primitive2d 779 } // end of namespace drawinglayer 780 781 ////////////////////////////////////////////////////////////////////////////// 782 // eof 783