1*464702f4SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*464702f4SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*464702f4SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*464702f4SAndrew Rist * distributed with this work for additional information 6*464702f4SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*464702f4SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*464702f4SAndrew Rist * "License"); you may not use this file except in compliance 9*464702f4SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*464702f4SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*464702f4SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*464702f4SAndrew Rist * software distributed under the License is distributed on an 15*464702f4SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*464702f4SAndrew Rist * KIND, either express or implied. See the License for the 17*464702f4SAndrew Rist * specific language governing permissions and limitations 18*464702f4SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*464702f4SAndrew Rist *************************************************************/ 21*464702f4SAndrew Rist 22*464702f4SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <drawinglayer/primitive2d/graphicprimitive2d.hxx> 28cdf0e10cSrcweir #include <drawinglayer/animation/animationtiming.hxx> 29cdf0e10cSrcweir #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 30cdf0e10cSrcweir #include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx> 31cdf0e10cSrcweir #include <drawinglayer/primitive2d/animatedprimitive2d.hxx> 32cdf0e10cSrcweir #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> 33cdf0e10cSrcweir #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 34cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 35cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 36cdf0e10cSrcweir #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 37cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 38cdf0e10cSrcweir 39cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 40cdf0e10cSrcweir // helper class for animated graphics 41cdf0e10cSrcweir 42cdf0e10cSrcweir #include <vcl/animate.hxx> 43cdf0e10cSrcweir #include <vcl/graph.hxx> 44cdf0e10cSrcweir #include <vcl/virdev.hxx> 45cdf0e10cSrcweir #include <vcl/svapp.hxx> 46cdf0e10cSrcweir #include <vcl/metaact.hxx> 47cdf0e10cSrcweir 48cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 49cdf0e10cSrcweir // includes for testing MetafilePrimitive2D::create2DDecomposition 50cdf0e10cSrcweir 51cdf0e10cSrcweir // this switch defines if the test code is included or not 52cdf0e10cSrcweir #undef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 53cdf0e10cSrcweir 54cdf0e10cSrcweir #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 55cdf0e10cSrcweir #include <vcl/gradient.hxx> 56cdf0e10cSrcweir #include <vcl/pngread.hxx> 57cdf0e10cSrcweir #include <vcl/lineinfo.hxx> 58cdf0e10cSrcweir #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 59cdf0e10cSrcweir 60cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 61cdf0e10cSrcweir 62cdf0e10cSrcweir namespace 63cdf0e10cSrcweir { 64cdf0e10cSrcweir struct animationStep 65cdf0e10cSrcweir { 66cdf0e10cSrcweir BitmapEx maBitmapEx; 67cdf0e10cSrcweir sal_uInt32 mnTime; 68cdf0e10cSrcweir }; 69cdf0e10cSrcweir 70cdf0e10cSrcweir class animatedBitmapExPreparator 71cdf0e10cSrcweir { 72cdf0e10cSrcweir ::Animation maAnimation; 73cdf0e10cSrcweir ::std::vector< animationStep > maSteps; 74cdf0e10cSrcweir 75cdf0e10cSrcweir sal_uInt32 generateStepTime(sal_uInt32 nIndex) const; 76cdf0e10cSrcweir 77cdf0e10cSrcweir public: 78cdf0e10cSrcweir animatedBitmapExPreparator(const Graphic& rGraphic); 79cdf0e10cSrcweir 80cdf0e10cSrcweir sal_uInt32 count() const { return maSteps.size(); } 81cdf0e10cSrcweir sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); } 82cdf0e10cSrcweir sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; } 83cdf0e10cSrcweir const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; } 84cdf0e10cSrcweir }; 85cdf0e10cSrcweir 86cdf0e10cSrcweir sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const 87cdf0e10cSrcweir { 88cdf0e10cSrcweir const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex)); 89cdf0e10cSrcweir sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10); 90cdf0e10cSrcweir 91cdf0e10cSrcweir // #115934# 92cdf0e10cSrcweir // Take care of special value for MultiPage TIFFs. ATM these shall just 93cdf0e10cSrcweir // show their first page. Later we will offer some switching when object 94cdf0e10cSrcweir // is selected. 95cdf0e10cSrcweir if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait) 96cdf0e10cSrcweir { 97cdf0e10cSrcweir // ATM the huge value would block the timer, so 98cdf0e10cSrcweir // use a long time to show first page (whole day) 99cdf0e10cSrcweir nWaitTime = 100 * 60 * 60 * 24; 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir // Bad trap: There are animated gifs with no set WaitTime (!). 103cdf0e10cSrcweir // In that case use a default value. 104cdf0e10cSrcweir if(0L == nWaitTime) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir nWaitTime = 100L; 107cdf0e10cSrcweir } 108cdf0e10cSrcweir 109cdf0e10cSrcweir return nWaitTime; 110cdf0e10cSrcweir } 111cdf0e10cSrcweir 112cdf0e10cSrcweir animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic) 113cdf0e10cSrcweir : maAnimation(rGraphic.GetAnimation()) 114cdf0e10cSrcweir { 115cdf0e10cSrcweir OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)"); 116cdf0e10cSrcweir 117cdf0e10cSrcweir // #128539# secure access to Animation, looks like there exist animated GIFs out there 118cdf0e10cSrcweir // with a step count of zero 119cdf0e10cSrcweir if(maAnimation.Count()) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir VirtualDevice aVirtualDevice(*Application::GetDefaultDevice()); 122cdf0e10cSrcweir VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L); 123cdf0e10cSrcweir 124cdf0e10cSrcweir // Prepare VirtualDevices and their states 125cdf0e10cSrcweir aVirtualDevice.EnableMapMode(sal_False); 126cdf0e10cSrcweir aVirtualDeviceMask.EnableMapMode(sal_False); 127cdf0e10cSrcweir aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel()); 128cdf0e10cSrcweir aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel()); 129cdf0e10cSrcweir aVirtualDevice.Erase(); 130cdf0e10cSrcweir aVirtualDeviceMask.Erase(); 131cdf0e10cSrcweir 132cdf0e10cSrcweir for(sal_uInt16 a(0L); a < maAnimation.Count(); a++) 133cdf0e10cSrcweir { 134cdf0e10cSrcweir animationStep aNextStep; 135cdf0e10cSrcweir aNextStep.mnTime = generateStepTime(a); 136cdf0e10cSrcweir 137cdf0e10cSrcweir // prepare step 138cdf0e10cSrcweir const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a)); 139cdf0e10cSrcweir 140cdf0e10cSrcweir switch(rAnimBitmap.eDisposal) 141cdf0e10cSrcweir { 142cdf0e10cSrcweir case DISPOSE_NOT: 143cdf0e10cSrcweir { 144cdf0e10cSrcweir aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); 145cdf0e10cSrcweir Bitmap aMask = rAnimBitmap.aBmpEx.GetMask(); 146cdf0e10cSrcweir 147cdf0e10cSrcweir if(aMask.IsEmpty()) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir const Point aEmpty; 150cdf0e10cSrcweir const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel()); 151cdf0e10cSrcweir const Wallpaper aWallpaper(COL_BLACK); 152cdf0e10cSrcweir aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper); 153cdf0e10cSrcweir } 154cdf0e10cSrcweir else 155cdf0e10cSrcweir { 156cdf0e10cSrcweir BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask); 157cdf0e10cSrcweir aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask); 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir break; 161cdf0e10cSrcweir } 162cdf0e10cSrcweir case DISPOSE_BACK: 163cdf0e10cSrcweir { 164cdf0e10cSrcweir // #i70772# react on no mask, for primitives, too. 165cdf0e10cSrcweir const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask()); 166cdf0e10cSrcweir const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap()); 167cdf0e10cSrcweir 168cdf0e10cSrcweir aVirtualDeviceMask.Erase(); 169cdf0e10cSrcweir aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent); 170cdf0e10cSrcweir 171cdf0e10cSrcweir if(aMask.IsEmpty()) 172cdf0e10cSrcweir { 173cdf0e10cSrcweir const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel()); 174cdf0e10cSrcweir aVirtualDeviceMask.SetFillColor(COL_BLACK); 175cdf0e10cSrcweir aVirtualDeviceMask.SetLineColor(); 176cdf0e10cSrcweir aVirtualDeviceMask.DrawRect(aRect); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir else 179cdf0e10cSrcweir { 180cdf0e10cSrcweir aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask); 181cdf0e10cSrcweir } 182cdf0e10cSrcweir 183cdf0e10cSrcweir break; 184cdf0e10cSrcweir } 185cdf0e10cSrcweir case DISPOSE_FULL: 186cdf0e10cSrcweir { 187cdf0e10cSrcweir aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); 188cdf0e10cSrcweir break; 189cdf0e10cSrcweir } 190cdf0e10cSrcweir case DISPOSE_PREVIOUS : 191cdf0e10cSrcweir { 192cdf0e10cSrcweir aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx); 193cdf0e10cSrcweir aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask()); 194cdf0e10cSrcweir break; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir } 197cdf0e10cSrcweir 198cdf0e10cSrcweir // create BitmapEx 199cdf0e10cSrcweir Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel()); 200cdf0e10cSrcweir Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap(Point(), aVirtualDeviceMask.GetOutputSizePixel()); 201cdf0e10cSrcweir aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap); 202cdf0e10cSrcweir 203cdf0e10cSrcweir // add to vector 204cdf0e10cSrcweir maSteps.push_back(aNextStep); 205cdf0e10cSrcweir } 206cdf0e10cSrcweir } 207cdf0e10cSrcweir } 208cdf0e10cSrcweir } // end of anonymous namespace 209cdf0e10cSrcweir 210cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 211cdf0e10cSrcweir 212cdf0e10cSrcweir namespace drawinglayer 213cdf0e10cSrcweir { 214cdf0e10cSrcweir namespace primitive2d 215cdf0e10cSrcweir { 216cdf0e10cSrcweir Primitive2DSequence GraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& 217cdf0e10cSrcweir #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 218cdf0e10cSrcweir rViewInformation 219cdf0e10cSrcweir #else 220cdf0e10cSrcweir /*rViewInformation*/ 221cdf0e10cSrcweir #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 222cdf0e10cSrcweir ) const 223cdf0e10cSrcweir { 224cdf0e10cSrcweir Primitive2DSequence aRetval; 225cdf0e10cSrcweir 226cdf0e10cSrcweir if(255L != getGraphicAttr().GetTransparency()) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir Primitive2DReference xPrimitive; 229cdf0e10cSrcweir 230cdf0e10cSrcweir // do not apply mirroring from GraphicAttr to the Metafile by calling 231cdf0e10cSrcweir // GetTransformedGraphic, this will try to mirror the Metafile using Scale() 232cdf0e10cSrcweir // at the Metafile. This again calls Scale at the single MetaFile actions, 233cdf0e10cSrcweir // but this implementation never worked. I reworked that implementations, 234cdf0e10cSrcweir // but for security reasons i will try not to use it. 235cdf0e10cSrcweir basegfx::B2DHomMatrix aTransform(getTransform()); 236cdf0e10cSrcweir 237cdf0e10cSrcweir if(getGraphicAttr().IsMirrored()) 238cdf0e10cSrcweir { 239cdf0e10cSrcweir // content needs mirroring 240cdf0e10cSrcweir const bool bHMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_HORZ); 241cdf0e10cSrcweir const bool bVMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_VERT); 242cdf0e10cSrcweir 243cdf0e10cSrcweir // mirror by applying negative scale to the unit primitive and 244cdf0e10cSrcweir // applying the object transformation on it. 245cdf0e10cSrcweir aTransform = basegfx::tools::createScaleB2DHomMatrix( 246cdf0e10cSrcweir bHMirr ? -1.0 : 1.0, 247cdf0e10cSrcweir bVMirr ? -1.0 : 1.0); 248cdf0e10cSrcweir aTransform.translate( 249cdf0e10cSrcweir bHMirr ? 1.0 : 0.0, 250cdf0e10cSrcweir bVMirr ? 1.0 : 0.0); 251cdf0e10cSrcweir aTransform = getTransform() * aTransform; 252cdf0e10cSrcweir } 253cdf0e10cSrcweir 254cdf0e10cSrcweir // Get transformed graphic. Suppress rotation and cropping, only filtering is needed 255cdf0e10cSrcweir // here (and may be replaced later on). Cropping is handled below as mask primitive (if set). 256cdf0e10cSrcweir // Also need to suppress mirroring, it is part of the transformation now (see above). 257cdf0e10cSrcweir GraphicAttr aSuppressGraphicAttr(getGraphicAttr()); 258cdf0e10cSrcweir aSuppressGraphicAttr.SetCrop(0, 0, 0, 0); 259cdf0e10cSrcweir aSuppressGraphicAttr.SetRotation(0); 260cdf0e10cSrcweir aSuppressGraphicAttr.SetMirrorFlags(0); 261cdf0e10cSrcweir 262cdf0e10cSrcweir const GraphicObject& rGraphicObject = getGraphicObject(); 263cdf0e10cSrcweir const Graphic aTransformedGraphic(rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr)); 264cdf0e10cSrcweir 265cdf0e10cSrcweir switch(aTransformedGraphic.GetType()) 266cdf0e10cSrcweir { 267cdf0e10cSrcweir case GRAPHIC_BITMAP : 268cdf0e10cSrcweir { 269cdf0e10cSrcweir if(aTransformedGraphic.IsAnimated()) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir // prepare animation data 272cdf0e10cSrcweir animatedBitmapExPreparator aData(aTransformedGraphic); 273cdf0e10cSrcweir 274cdf0e10cSrcweir if(aData.count()) 275cdf0e10cSrcweir { 276cdf0e10cSrcweir // create sub-primitives for animated bitmap and the needed animation loop 277cdf0e10cSrcweir animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff); 278cdf0e10cSrcweir Primitive2DSequence aBitmapPrimitives(aData.count()); 279cdf0e10cSrcweir 280cdf0e10cSrcweir for(sal_uInt32 a(0L); a < aData.count(); a++) 281cdf0e10cSrcweir { 282cdf0e10cSrcweir animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count()); 283cdf0e10cSrcweir aAnimationLoop.append(aTime); 284cdf0e10cSrcweir const Primitive2DReference xRef(new BitmapPrimitive2D(aData.stepBitmapEx(a), aTransform)); 285cdf0e10cSrcweir aBitmapPrimitives[a] = xRef; 286cdf0e10cSrcweir } 287cdf0e10cSrcweir 288cdf0e10cSrcweir // prepare animation list 289cdf0e10cSrcweir animation::AnimationEntryList aAnimationList; 290cdf0e10cSrcweir aAnimationList.append(aAnimationLoop); 291cdf0e10cSrcweir 292cdf0e10cSrcweir // create and add animated switch primitive 293cdf0e10cSrcweir xPrimitive = Primitive2DReference(new AnimatedSwitchPrimitive2D(aAnimationList, aBitmapPrimitives, false)); 294cdf0e10cSrcweir } 295cdf0e10cSrcweir } 296cdf0e10cSrcweir else 297cdf0e10cSrcweir { 298cdf0e10cSrcweir xPrimitive = Primitive2DReference(new BitmapPrimitive2D(aTransformedGraphic.GetBitmapEx(), aTransform)); 299cdf0e10cSrcweir } 300cdf0e10cSrcweir 301cdf0e10cSrcweir break; 302cdf0e10cSrcweir } 303cdf0e10cSrcweir 304cdf0e10cSrcweir case GRAPHIC_GDIMETAFILE : 305cdf0e10cSrcweir { 306cdf0e10cSrcweir #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 307cdf0e10cSrcweir static bool bDoTest(false); 308cdf0e10cSrcweir 309cdf0e10cSrcweir if(bDoTest) 310cdf0e10cSrcweir { 311cdf0e10cSrcweir // All this is/was test code for testing MetafilePrimitive2D::create2DDecomposition 312cdf0e10cSrcweir // extensively. It may be needed again when diverse actions need debugging, so i leave 313cdf0e10cSrcweir // it in here, but take it out using USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE. 314cdf0e10cSrcweir // Use it by compiling with the code, insert any DrawObject, convert to Metafile. The 315cdf0e10cSrcweir // debugger will then stop here (when breakpoint set, of course). You may enter single 316cdf0e10cSrcweir // parts of actions and/or change to true what You want to check. 317cdf0e10cSrcweir GDIMetaFile aMtf; 318cdf0e10cSrcweir VirtualDevice aOut; 319cdf0e10cSrcweir const basegfx::B2DRange aRange(getB2DRange(rViewInformation)); 320cdf0e10cSrcweir const Rectangle aRectangle( 321cdf0e10cSrcweir basegfx::fround(aRange.getMinX()), basegfx::fround(aRange.getMinY()), 322cdf0e10cSrcweir basegfx::fround(aRange.getMaxX()), basegfx::fround(aRange.getMaxY())); 323cdf0e10cSrcweir const Point aOrigin(aRectangle.TopLeft()); 324cdf0e10cSrcweir const Fraction aScaleX(aRectangle.getWidth()); 325cdf0e10cSrcweir const Fraction aScaleY(aRectangle.getHeight()); 326cdf0e10cSrcweir MapMode aMapMode(MAP_100TH_MM, aOrigin, aScaleX, aScaleY); 327cdf0e10cSrcweir 328cdf0e10cSrcweir Size aDummySize(2, 2); 329cdf0e10cSrcweir aOut.SetOutputSizePixel(aDummySize); 330cdf0e10cSrcweir aOut.EnableOutput(FALSE); 331cdf0e10cSrcweir aOut.SetMapMode(aMapMode); 332cdf0e10cSrcweir 333cdf0e10cSrcweir aMtf.Clear(); 334cdf0e10cSrcweir aMtf.Record(&aOut); 335cdf0e10cSrcweir 336cdf0e10cSrcweir const Fraction aNeutralFraction(1, 1); 337cdf0e10cSrcweir const MapMode aRelativeMapMode( 338cdf0e10cSrcweir MAP_RELATIVE, 339cdf0e10cSrcweir Point(-aRectangle.Left(), -aRectangle.Top()), 340cdf0e10cSrcweir aNeutralFraction, aNeutralFraction); 341cdf0e10cSrcweir aOut.SetMapMode(aRelativeMapMode); 342cdf0e10cSrcweir 343cdf0e10cSrcweir if(false) 344cdf0e10cSrcweir { 345cdf0e10cSrcweir const sal_Int32 nHor(aRectangle.getWidth() / 4); 346cdf0e10cSrcweir const sal_Int32 nVer(aRectangle.getHeight() / 4); 347cdf0e10cSrcweir const Rectangle aCenteredRectangle( 348cdf0e10cSrcweir aRectangle.Left() + nHor, aRectangle.Top() + nVer, 349cdf0e10cSrcweir aRectangle.Right() - nHor, aRectangle.Bottom() - nVer); 350cdf0e10cSrcweir aOut.SetClipRegion(aCenteredRectangle); 351cdf0e10cSrcweir } 352cdf0e10cSrcweir 353cdf0e10cSrcweir if(false) 354cdf0e10cSrcweir { 355cdf0e10cSrcweir const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight()); 356cdf0e10cSrcweir aOut.IntersectClipRegion(aRightRectangle); 357cdf0e10cSrcweir } 358cdf0e10cSrcweir 359cdf0e10cSrcweir if(false) 360cdf0e10cSrcweir { 361cdf0e10cSrcweir const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight()); 362cdf0e10cSrcweir const Rectangle aBottomRectangle(aRectangle.LeftCenter(), aRectangle.BottomRight()); 363cdf0e10cSrcweir Region aRegion(aRightRectangle); 364cdf0e10cSrcweir aRegion.Intersect(aBottomRectangle); 365cdf0e10cSrcweir aOut.IntersectClipRegion(aRegion); 366cdf0e10cSrcweir } 367cdf0e10cSrcweir 368cdf0e10cSrcweir if(false) 369cdf0e10cSrcweir { 370cdf0e10cSrcweir const sal_Int32 nHor(aRectangle.getWidth() / 10); 371cdf0e10cSrcweir const sal_Int32 nVer(aRectangle.getHeight() / 10); 372cdf0e10cSrcweir aOut.MoveClipRegion(nHor, nVer); 373cdf0e10cSrcweir } 374cdf0e10cSrcweir 375cdf0e10cSrcweir if(false) 376cdf0e10cSrcweir { 377cdf0e10cSrcweir Wallpaper aWallpaper(Color(COL_BLACK)); 378cdf0e10cSrcweir aOut.DrawWallpaper(aRectangle, aWallpaper); 379cdf0e10cSrcweir } 380cdf0e10cSrcweir 381cdf0e10cSrcweir if(false) 382cdf0e10cSrcweir { 383cdf0e10cSrcweir Wallpaper aWallpaper(Gradient(GRADIENT_LINEAR, Color(COL_RED), Color(COL_GREEN))); 384cdf0e10cSrcweir aOut.DrawWallpaper(aRectangle, aWallpaper); 385cdf0e10cSrcweir } 386cdf0e10cSrcweir 387cdf0e10cSrcweir if(false) 388cdf0e10cSrcweir { 389cdf0e10cSrcweir SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); 390cdf0e10cSrcweir vcl::PNGReader aPNGReader(aRead); 391cdf0e10cSrcweir BitmapEx aBitmapEx(aPNGReader.Read()); 392cdf0e10cSrcweir Wallpaper aWallpaper(aBitmapEx); 393cdf0e10cSrcweir aOut.DrawWallpaper(aRectangle, aWallpaper); 394cdf0e10cSrcweir } 395cdf0e10cSrcweir 396cdf0e10cSrcweir if(false) 397cdf0e10cSrcweir { 398cdf0e10cSrcweir const double fHor(aRectangle.getWidth()); 399cdf0e10cSrcweir const double fVer(aRectangle.getHeight()); 400cdf0e10cSrcweir Color aColor(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)); 401cdf0e10cSrcweir 402cdf0e10cSrcweir for(sal_uInt32 a(0); a < 5000; a++) 403cdf0e10cSrcweir { 404cdf0e10cSrcweir const Point aPoint( 405cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 406cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 407cdf0e10cSrcweir 408cdf0e10cSrcweir if(!(a % 3)) 409cdf0e10cSrcweir { 410cdf0e10cSrcweir aColor = Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)); 411cdf0e10cSrcweir } 412cdf0e10cSrcweir 413cdf0e10cSrcweir aOut.DrawPixel(aPoint, aColor); 414cdf0e10cSrcweir } 415cdf0e10cSrcweir } 416cdf0e10cSrcweir 417cdf0e10cSrcweir if(false) 418cdf0e10cSrcweir { 419cdf0e10cSrcweir const double fHor(aRectangle.getWidth()); 420cdf0e10cSrcweir const double fVer(aRectangle.getHeight()); 421cdf0e10cSrcweir 422cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 423cdf0e10cSrcweir aOut.SetFillColor(); 424cdf0e10cSrcweir 425cdf0e10cSrcweir for(sal_uInt32 a(0); a < 5000; a++) 426cdf0e10cSrcweir { 427cdf0e10cSrcweir const Point aPoint( 428cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 429cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 430cdf0e10cSrcweir aOut.DrawPixel(aPoint); 431cdf0e10cSrcweir } 432cdf0e10cSrcweir } 433cdf0e10cSrcweir 434cdf0e10cSrcweir if(false) 435cdf0e10cSrcweir { 436cdf0e10cSrcweir const double fHor(aRectangle.getWidth()); 437cdf0e10cSrcweir const double fVer(aRectangle.getHeight()); 438cdf0e10cSrcweir 439cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 440cdf0e10cSrcweir aOut.SetFillColor(); 441cdf0e10cSrcweir 442cdf0e10cSrcweir Point aStart( 443cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 444cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 445cdf0e10cSrcweir Point aStop( 446cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 447cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 448cdf0e10cSrcweir 449cdf0e10cSrcweir LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0)); 450cdf0e10cSrcweir bool bUseLineInfo(false); 451cdf0e10cSrcweir 452cdf0e10cSrcweir for(sal_uInt32 a(0); a < 20; a++) 453cdf0e10cSrcweir { 454cdf0e10cSrcweir if(!(a%6)) 455cdf0e10cSrcweir { 456cdf0e10cSrcweir bUseLineInfo = !bUseLineInfo; 457cdf0e10cSrcweir } 458cdf0e10cSrcweir 459cdf0e10cSrcweir if(!(a%4)) 460cdf0e10cSrcweir { 461cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 462cdf0e10cSrcweir } 463cdf0e10cSrcweir 464cdf0e10cSrcweir if(a%3) 465cdf0e10cSrcweir { 466cdf0e10cSrcweir aStart = aStop; 467cdf0e10cSrcweir aStop = Point( 468cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 469cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 470cdf0e10cSrcweir } 471cdf0e10cSrcweir else 472cdf0e10cSrcweir { 473cdf0e10cSrcweir aStart = Point( 474cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 475cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 476cdf0e10cSrcweir aStop = Point( 477cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 478cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 479cdf0e10cSrcweir } 480cdf0e10cSrcweir 481cdf0e10cSrcweir if(bUseLineInfo) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir aOut.DrawLine(aStart, aStop, aLineInfo); 484cdf0e10cSrcweir } 485cdf0e10cSrcweir else 486cdf0e10cSrcweir { 487cdf0e10cSrcweir aOut.DrawLine(aStart, aStop); 488cdf0e10cSrcweir } 489cdf0e10cSrcweir } 490cdf0e10cSrcweir } 491cdf0e10cSrcweir 492cdf0e10cSrcweir if(false) 493cdf0e10cSrcweir { 494cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 495cdf0e10cSrcweir aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 496cdf0e10cSrcweir aOut.DrawRect(aRectangle); 497cdf0e10cSrcweir } 498cdf0e10cSrcweir 499cdf0e10cSrcweir if(false) 500cdf0e10cSrcweir { 501cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 502cdf0e10cSrcweir aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 503cdf0e10cSrcweir const sal_uInt32 nHor(aRectangle.getWidth() / 10); 504cdf0e10cSrcweir const sal_uInt32 nVer(aRectangle.getHeight() / 10); 505cdf0e10cSrcweir aOut.DrawRect(aRectangle, nHor, nVer); 506cdf0e10cSrcweir } 507cdf0e10cSrcweir 508cdf0e10cSrcweir if(false) 509cdf0e10cSrcweir { 510cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 511cdf0e10cSrcweir aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 512cdf0e10cSrcweir aOut.DrawEllipse(aRectangle); 513cdf0e10cSrcweir } 514cdf0e10cSrcweir 515cdf0e10cSrcweir if(false) 516cdf0e10cSrcweir { 517cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 518cdf0e10cSrcweir aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 519cdf0e10cSrcweir aOut.DrawArc(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter()); 520cdf0e10cSrcweir } 521cdf0e10cSrcweir 522cdf0e10cSrcweir if(false) 523cdf0e10cSrcweir { 524cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 525cdf0e10cSrcweir aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 526cdf0e10cSrcweir aOut.DrawPie(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter()); 527cdf0e10cSrcweir } 528cdf0e10cSrcweir 529cdf0e10cSrcweir if(false) 530cdf0e10cSrcweir { 531cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 532cdf0e10cSrcweir aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 533cdf0e10cSrcweir aOut.DrawChord(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter()); 534cdf0e10cSrcweir } 535cdf0e10cSrcweir 536cdf0e10cSrcweir if(false) 537cdf0e10cSrcweir { 538cdf0e10cSrcweir const double fHor(aRectangle.getWidth()); 539cdf0e10cSrcweir const double fVer(aRectangle.getHeight()); 540cdf0e10cSrcweir 541cdf0e10cSrcweir for(sal_uInt32 b(0); b < 5; b++) 542cdf0e10cSrcweir { 543cdf0e10cSrcweir const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0))); 544cdf0e10cSrcweir const bool bClose(basegfx::fround(rand() / 32767.0)); 545cdf0e10cSrcweir Polygon aPolygon(nCount + (bClose ? 1 : 0)); 546cdf0e10cSrcweir 547cdf0e10cSrcweir for(sal_uInt32 a(0); a < nCount; a++) 548cdf0e10cSrcweir { 549cdf0e10cSrcweir const Point aPoint( 550cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 551cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 552cdf0e10cSrcweir aPolygon[a] = aPoint; 553cdf0e10cSrcweir } 554cdf0e10cSrcweir 555cdf0e10cSrcweir if(bClose) 556cdf0e10cSrcweir { 557cdf0e10cSrcweir aPolygon[aPolygon.GetSize() - 1] = aPolygon[0]; 558cdf0e10cSrcweir } 559cdf0e10cSrcweir 560cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 561cdf0e10cSrcweir aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 562cdf0e10cSrcweir 563cdf0e10cSrcweir if(!(b%2)) 564cdf0e10cSrcweir { 565cdf0e10cSrcweir const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0)); 566cdf0e10cSrcweir aOut.DrawPolyLine(aPolygon, aLineInfo); 567cdf0e10cSrcweir } 568cdf0e10cSrcweir else 569cdf0e10cSrcweir { 570cdf0e10cSrcweir aOut.DrawPolyLine(aPolygon); 571cdf0e10cSrcweir } 572cdf0e10cSrcweir } 573cdf0e10cSrcweir } 574cdf0e10cSrcweir 575cdf0e10cSrcweir if(false) 576cdf0e10cSrcweir { 577cdf0e10cSrcweir const double fHor(aRectangle.getWidth()); 578cdf0e10cSrcweir const double fVer(aRectangle.getHeight()); 579cdf0e10cSrcweir 580cdf0e10cSrcweir for(sal_uInt32 b(0); b < 5; b++) 581cdf0e10cSrcweir { 582cdf0e10cSrcweir const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0))); 583cdf0e10cSrcweir const bool bClose(basegfx::fround(rand() / 32767.0)); 584cdf0e10cSrcweir Polygon aPolygon(nCount + (bClose ? 1 : 0)); 585cdf0e10cSrcweir 586cdf0e10cSrcweir for(sal_uInt32 a(0); a < nCount; a++) 587cdf0e10cSrcweir { 588cdf0e10cSrcweir const Point aPoint( 589cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 590cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 591cdf0e10cSrcweir aPolygon[a] = aPoint; 592cdf0e10cSrcweir } 593cdf0e10cSrcweir 594cdf0e10cSrcweir if(bClose) 595cdf0e10cSrcweir { 596cdf0e10cSrcweir aPolygon[aPolygon.GetSize() - 1] = aPolygon[0]; 597cdf0e10cSrcweir } 598cdf0e10cSrcweir 599cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 600cdf0e10cSrcweir aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 601cdf0e10cSrcweir aOut.DrawPolygon(aPolygon); 602cdf0e10cSrcweir } 603cdf0e10cSrcweir } 604cdf0e10cSrcweir 605cdf0e10cSrcweir if(false) 606cdf0e10cSrcweir { 607cdf0e10cSrcweir const double fHor(aRectangle.getWidth()); 608cdf0e10cSrcweir const double fVer(aRectangle.getHeight()); 609cdf0e10cSrcweir PolyPolygon aPolyPolygon; 610cdf0e10cSrcweir 611cdf0e10cSrcweir for(sal_uInt32 b(0); b < 3; b++) 612cdf0e10cSrcweir { 613cdf0e10cSrcweir const sal_uInt32 nCount(basegfx::fround(rand() * (6 / 32767.0))); 614cdf0e10cSrcweir const bool bClose(basegfx::fround(rand() / 32767.0)); 615cdf0e10cSrcweir Polygon aPolygon(nCount + (bClose ? 1 : 0)); 616cdf0e10cSrcweir 617cdf0e10cSrcweir for(sal_uInt32 a(0); a < nCount; a++) 618cdf0e10cSrcweir { 619cdf0e10cSrcweir const Point aPoint( 620cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)), 621cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0))); 622cdf0e10cSrcweir aPolygon[a] = aPoint; 623cdf0e10cSrcweir } 624cdf0e10cSrcweir 625cdf0e10cSrcweir if(bClose) 626cdf0e10cSrcweir { 627cdf0e10cSrcweir aPolygon[aPolygon.GetSize() - 1] = aPolygon[0]; 628cdf0e10cSrcweir } 629cdf0e10cSrcweir 630cdf0e10cSrcweir aPolyPolygon.Insert(aPolygon); 631cdf0e10cSrcweir } 632cdf0e10cSrcweir 633cdf0e10cSrcweir aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 634cdf0e10cSrcweir aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0))); 635cdf0e10cSrcweir aOut.DrawPolyPolygon(aPolyPolygon); 636cdf0e10cSrcweir } 637cdf0e10cSrcweir 638cdf0e10cSrcweir if(false) 639cdf0e10cSrcweir { 640cdf0e10cSrcweir SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); 641cdf0e10cSrcweir vcl::PNGReader aPNGReader(aRead); 642cdf0e10cSrcweir BitmapEx aBitmapEx(aPNGReader.Read()); 643cdf0e10cSrcweir aOut.DrawBitmapEx(aRectangle.TopLeft(), aBitmapEx); 644cdf0e10cSrcweir } 645cdf0e10cSrcweir 646cdf0e10cSrcweir if(false) 647cdf0e10cSrcweir { 648cdf0e10cSrcweir SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); 649cdf0e10cSrcweir vcl::PNGReader aPNGReader(aRead); 650cdf0e10cSrcweir BitmapEx aBitmapEx(aPNGReader.Read()); 651cdf0e10cSrcweir aOut.DrawBitmapEx(aRectangle.TopLeft(), aRectangle.GetSize(), aBitmapEx); 652cdf0e10cSrcweir } 653cdf0e10cSrcweir 654cdf0e10cSrcweir if(false) 655cdf0e10cSrcweir { 656cdf0e10cSrcweir SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ); 657cdf0e10cSrcweir vcl::PNGReader aPNGReader(aRead); 658cdf0e10cSrcweir BitmapEx aBitmapEx(aPNGReader.Read()); 659cdf0e10cSrcweir const Size aSizePixel(aBitmapEx.GetSizePixel()); 660cdf0e10cSrcweir aOut.DrawBitmapEx( 661cdf0e10cSrcweir aRectangle.TopLeft(), 662cdf0e10cSrcweir aRectangle.GetSize(), 663cdf0e10cSrcweir Point(0, 0), 664cdf0e10cSrcweir Size(aSizePixel.Width() /2, aSizePixel.Height() / 2), 665cdf0e10cSrcweir aBitmapEx); 666cdf0e10cSrcweir } 667cdf0e10cSrcweir 668cdf0e10cSrcweir if(false) 669cdf0e10cSrcweir { 670cdf0e10cSrcweir const double fHor(aRectangle.getWidth()); 671cdf0e10cSrcweir const double fVer(aRectangle.getHeight()); 672cdf0e10cSrcweir const Point aPointA( 673cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(fHor * 0.2), 674cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(fVer * 0.3)); 675cdf0e10cSrcweir const Point aPointB( 676cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(fHor * 0.2), 677cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(fVer * 0.5)); 678cdf0e10cSrcweir const Point aPointC( 679cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(fHor * 0.2), 680cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(fVer * 0.7)); 681cdf0e10cSrcweir const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8); 682cdf0e10cSrcweir 683cdf0e10cSrcweir const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8); 684cdf0e10cSrcweir Font aFont(aFontName, Size(0, 1000)); 685cdf0e10cSrcweir aFont.SetAlign(ALIGN_BASELINE); 686cdf0e10cSrcweir aFont.SetColor(COL_RED); 687cdf0e10cSrcweir //sal_Int32* pDXArray = new sal_Int32[aText.Len()]; 688cdf0e10cSrcweir 689cdf0e10cSrcweir aFont.SetOutline(true); 690cdf0e10cSrcweir aOut.SetFont(aFont); 691cdf0e10cSrcweir aOut.DrawText(aPointA, aText, 0, aText.Len()); 692cdf0e10cSrcweir 693cdf0e10cSrcweir aFont.SetShadow(true); 694cdf0e10cSrcweir aOut.SetFont(aFont); 695cdf0e10cSrcweir aOut.DrawText(aPointB, aText, 0, aText.Len()); 696cdf0e10cSrcweir 697cdf0e10cSrcweir aFont.SetRelief(RELIEF_EMBOSSED); 698cdf0e10cSrcweir aOut.SetFont(aFont); 699cdf0e10cSrcweir aOut.DrawText(aPointC, aText, 0, aText.Len()); 700cdf0e10cSrcweir 701cdf0e10cSrcweir //delete pDXArray; 702cdf0e10cSrcweir } 703cdf0e10cSrcweir 704cdf0e10cSrcweir if(false) 705cdf0e10cSrcweir { 706cdf0e10cSrcweir const double fHor(aRectangle.getWidth()); 707cdf0e10cSrcweir const double fVer(aRectangle.getHeight()); 708cdf0e10cSrcweir const Point aPointA( 709cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(fHor * 0.2), 710cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(fVer * 0.3)); 711cdf0e10cSrcweir const Point aPointB( 712cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(fHor * 0.2), 713cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(fVer * 0.5)); 714cdf0e10cSrcweir const Point aPointC( 715cdf0e10cSrcweir aRectangle.Left() + basegfx::fround(fHor * 0.2), 716cdf0e10cSrcweir aRectangle.Top() + basegfx::fround(fVer * 0.7)); 717cdf0e10cSrcweir const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8); 718cdf0e10cSrcweir 719cdf0e10cSrcweir const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8); 720cdf0e10cSrcweir Font aFont(aFontName, Size(0, 1000)); 721cdf0e10cSrcweir aFont.SetAlign(ALIGN_BASELINE); 722cdf0e10cSrcweir aFont.SetColor(COL_RED); 723cdf0e10cSrcweir 724cdf0e10cSrcweir aOut.SetFont(aFont); 725cdf0e10cSrcweir const sal_Int32 nWidth(aOut.GetTextWidth(aText, 0, aText.Len())); 726cdf0e10cSrcweir aOut.DrawText(aPointA, aText, 0, aText.Len()); 727cdf0e10cSrcweir aOut.DrawTextLine(aPointA, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); 728cdf0e10cSrcweir aOut.DrawTextLine(aPointB, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); 729cdf0e10cSrcweir aOut.DrawTextLine(aPointC, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); 730cdf0e10cSrcweir } 731cdf0e10cSrcweir 732cdf0e10cSrcweir aMtf.Stop(); 733cdf0e10cSrcweir aMtf.WindStart(); 734cdf0e10cSrcweir aMtf.SetPrefMapMode(MapMode(MAP_100TH_MM)); 735cdf0e10cSrcweir aMtf.SetPrefSize(Size(aRectangle.getWidth(), aRectangle.getHeight())); 736cdf0e10cSrcweir 737cdf0e10cSrcweir xPrimitive = Primitive2DReference( 738cdf0e10cSrcweir new MetafilePrimitive2D( 739cdf0e10cSrcweir aTransform, 740cdf0e10cSrcweir aMtf)); 741cdf0e10cSrcweir } 742cdf0e10cSrcweir else 743cdf0e10cSrcweir { 744cdf0e10cSrcweir #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 745cdf0e10cSrcweir // create MetafilePrimitive2D 746cdf0e10cSrcweir const GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile(); 747cdf0e10cSrcweir 748cdf0e10cSrcweir if( aTransformedGraphic.IsRenderGraphic() ) 749cdf0e10cSrcweir { 750cdf0e10cSrcweir xPrimitive = Primitive2DReference( 751cdf0e10cSrcweir new RenderGraphicPrimitive2D( 752cdf0e10cSrcweir static_cast< MetaRenderGraphicAction* >(rMetafile.GetAction(0))->GetRenderGraphic(), 753cdf0e10cSrcweir aTransform)); 754cdf0e10cSrcweir } 755cdf0e10cSrcweir else 756cdf0e10cSrcweir { 757cdf0e10cSrcweir xPrimitive = Primitive2DReference( 758cdf0e10cSrcweir new MetafilePrimitive2D( 759cdf0e10cSrcweir aTransform, 760cdf0e10cSrcweir rMetafile)); 761cdf0e10cSrcweir 762cdf0e10cSrcweir // #i100357# find out if clipping is needed for this primitive. Unfortunately, 763cdf0e10cSrcweir // there exist Metafiles who's content is bigger than the proposed PrefSize set 764cdf0e10cSrcweir // at them. This is an error, but we need to work around this 765cdf0e10cSrcweir const Size aMetaFilePrefSize(rMetafile.GetPrefSize()); 766cdf0e10cSrcweir const Size aMetaFileRealSize( 767cdf0e10cSrcweir const_cast< GDIMetaFile& >(rMetafile).GetBoundRect( 768cdf0e10cSrcweir *Application::GetDefaultDevice()).GetSize()); 769cdf0e10cSrcweir 770cdf0e10cSrcweir if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth() 771cdf0e10cSrcweir || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight()) 772cdf0e10cSrcweir { 773cdf0e10cSrcweir // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon 774cdf0e10cSrcweir const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1); 775cdf0e10cSrcweir basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon()); 776cdf0e10cSrcweir aMaskPolygon.transform(aTransform); 777cdf0e10cSrcweir 778cdf0e10cSrcweir xPrimitive = Primitive2DReference( 779cdf0e10cSrcweir new MaskPrimitive2D( 780cdf0e10cSrcweir basegfx::B2DPolyPolygon(aMaskPolygon), 781cdf0e10cSrcweir aChildContent)); 782cdf0e10cSrcweir } 783cdf0e10cSrcweir } 784cdf0e10cSrcweir #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 785cdf0e10cSrcweir } 786cdf0e10cSrcweir #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 787cdf0e10cSrcweir 788cdf0e10cSrcweir break; 789cdf0e10cSrcweir } 790cdf0e10cSrcweir 791cdf0e10cSrcweir default: 792cdf0e10cSrcweir { 793cdf0e10cSrcweir // nothing to create 794cdf0e10cSrcweir break; 795cdf0e10cSrcweir } 796cdf0e10cSrcweir } 797cdf0e10cSrcweir 798cdf0e10cSrcweir if(xPrimitive.is()) 799cdf0e10cSrcweir { 800cdf0e10cSrcweir // check for cropping 801cdf0e10cSrcweir if(getGraphicAttr().IsCropped()) 802cdf0e10cSrcweir { 803cdf0e10cSrcweir // decompose to get current pos and size 804cdf0e10cSrcweir basegfx::B2DVector aScale, aTranslate; 805cdf0e10cSrcweir double fRotate, fShearX; 806cdf0e10cSrcweir getTransform().decompose(aScale, aTranslate, fRotate, fShearX); 807cdf0e10cSrcweir 808cdf0e10cSrcweir // create ranges. The current object range is just scale and translate 809cdf0e10cSrcweir const basegfx::B2DRange aCurrent( 810cdf0e10cSrcweir aTranslate.getX(), aTranslate.getY(), 811cdf0e10cSrcweir aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY()); 812cdf0e10cSrcweir 813cdf0e10cSrcweir // calculate scalings between real image size and logic object size. This 814cdf0e10cSrcweir // is necessary since the crop values are relative to original bitmap size 815cdf0e10cSrcweir double fFactorX(1.0); 816cdf0e10cSrcweir double fFactorY(1.0); 817cdf0e10cSrcweir 818cdf0e10cSrcweir { 819cdf0e10cSrcweir const MapMode aMapMode100thmm(MAP_100TH_MM); 820cdf0e10cSrcweir Size aBitmapSize(rGraphicObject.GetPrefSize()); 821cdf0e10cSrcweir 822cdf0e10cSrcweir // #i95968# better support PrefMapMode; special for MAP_PIXEL was missing 823cdf0e10cSrcweir if(MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit()) 824cdf0e10cSrcweir { 825cdf0e10cSrcweir aBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aBitmapSize, aMapMode100thmm); 826cdf0e10cSrcweir } 827cdf0e10cSrcweir else 828cdf0e10cSrcweir { 829cdf0e10cSrcweir aBitmapSize = Application::GetDefaultDevice()->LogicToLogic(aBitmapSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm); 830cdf0e10cSrcweir } 831cdf0e10cSrcweir 832cdf0e10cSrcweir const double fDivX(aBitmapSize.Width() - getGraphicAttr().GetLeftCrop() - getGraphicAttr().GetRightCrop()); 833cdf0e10cSrcweir const double fDivY(aBitmapSize.Height() - getGraphicAttr().GetTopCrop() - getGraphicAttr().GetBottomCrop()); 834cdf0e10cSrcweir 835cdf0e10cSrcweir if(!basegfx::fTools::equalZero(fDivX)) 836cdf0e10cSrcweir { 837cdf0e10cSrcweir fFactorX = aScale.getX() / fDivX; 838cdf0e10cSrcweir } 839cdf0e10cSrcweir 840cdf0e10cSrcweir if(!basegfx::fTools::equalZero(fDivY)) 841cdf0e10cSrcweir { 842cdf0e10cSrcweir fFactorY = aScale.getY() / fDivY; 843cdf0e10cSrcweir } 844cdf0e10cSrcweir } 845cdf0e10cSrcweir 846cdf0e10cSrcweir // Create cropped range, describes the bounds of the original graphic 847cdf0e10cSrcweir basegfx::B2DRange aCropped; 848cdf0e10cSrcweir aCropped.expand(aCurrent.getMinimum() - basegfx::B2DPoint(getGraphicAttr().GetLeftCrop() * fFactorX, getGraphicAttr().GetTopCrop() * fFactorY)); 849cdf0e10cSrcweir aCropped.expand(aCurrent.getMaximum() + basegfx::B2DPoint(getGraphicAttr().GetRightCrop() * fFactorX, getGraphicAttr().GetBottomCrop() * fFactorY)); 850cdf0e10cSrcweir 851cdf0e10cSrcweir if(aCropped.isEmpty()) 852cdf0e10cSrcweir { 853cdf0e10cSrcweir // nothing to add since cropped bitmap is completely empty 854cdf0e10cSrcweir // xPrimitive will not be used 855cdf0e10cSrcweir } 856cdf0e10cSrcweir else 857cdf0e10cSrcweir { 858cdf0e10cSrcweir // build new object transformation for transform primitive which contains xPrimitive 859cdf0e10cSrcweir basegfx::B2DHomMatrix aNewObjectTransform(getTransform()); 860cdf0e10cSrcweir aNewObjectTransform.invert(); 861cdf0e10cSrcweir aNewObjectTransform = basegfx::tools::createScaleTranslateB2DHomMatrix( 862cdf0e10cSrcweir aCropped.getWidth(), aCropped.getHeight(), 863cdf0e10cSrcweir aCropped.getMinX() - aCurrent.getMinX(), aCropped.getMinY() - aCurrent.getMinY()) 864cdf0e10cSrcweir * aNewObjectTransform; 865cdf0e10cSrcweir 866cdf0e10cSrcweir // add shear, rotate and translate using combined matrix to speedup 867cdf0e10cSrcweir const basegfx::B2DHomMatrix aCombinedMatrix(basegfx::tools::createShearXRotateTranslateB2DHomMatrix( 868cdf0e10cSrcweir fShearX, fRotate, aTranslate.getX(), aTranslate.getY())); 869cdf0e10cSrcweir aNewObjectTransform = aCombinedMatrix * aNewObjectTransform; 870cdf0e10cSrcweir 871cdf0e10cSrcweir // prepare TransformPrimitive2D with xPrimitive 872cdf0e10cSrcweir const Primitive2DReference xTransformPrimitive(new TransformPrimitive2D(aNewObjectTransform, Primitive2DSequence(&xPrimitive, 1L))); 873cdf0e10cSrcweir 874cdf0e10cSrcweir if(aCurrent.isInside(aCropped)) 875cdf0e10cSrcweir { 876cdf0e10cSrcweir // cropped just got smaller, no need to really use a mask. Add to destination directly 877cdf0e10cSrcweir appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xTransformPrimitive); 878cdf0e10cSrcweir } 879cdf0e10cSrcweir else 880cdf0e10cSrcweir { 881cdf0e10cSrcweir // cropped got bigger, mask it with original object's bounds 882cdf0e10cSrcweir basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::tools::createUnitPolygon()); 883cdf0e10cSrcweir aMaskPolyPolygon.transform(getTransform()); 884cdf0e10cSrcweir 885cdf0e10cSrcweir // create maskPrimitive with aMaskPolyPolygon and aMaskContentVector 886cdf0e10cSrcweir const Primitive2DReference xRefB(new MaskPrimitive2D(aMaskPolyPolygon, Primitive2DSequence(&xTransformPrimitive, 1L))); 887cdf0e10cSrcweir appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRefB); 888cdf0e10cSrcweir } 889cdf0e10cSrcweir } 890cdf0e10cSrcweir } 891cdf0e10cSrcweir else 892cdf0e10cSrcweir { 893cdf0e10cSrcweir // add to decomposition 894cdf0e10cSrcweir appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xPrimitive); 895cdf0e10cSrcweir } 896cdf0e10cSrcweir } 897cdf0e10cSrcweir } 898cdf0e10cSrcweir 899cdf0e10cSrcweir return aRetval; 900cdf0e10cSrcweir } 901cdf0e10cSrcweir 902cdf0e10cSrcweir GraphicPrimitive2D::GraphicPrimitive2D( 903cdf0e10cSrcweir const basegfx::B2DHomMatrix& rTransform, 904cdf0e10cSrcweir const GraphicObject& rGraphicObject, 905cdf0e10cSrcweir const GraphicAttr& rGraphicAttr) 906cdf0e10cSrcweir : BufferedDecompositionPrimitive2D(), 907cdf0e10cSrcweir maTransform(rTransform), 908cdf0e10cSrcweir maGraphicObject(rGraphicObject), 909cdf0e10cSrcweir maGraphicAttr(rGraphicAttr) 910cdf0e10cSrcweir { 911cdf0e10cSrcweir } 912cdf0e10cSrcweir 913cdf0e10cSrcweir GraphicPrimitive2D::GraphicPrimitive2D( 914cdf0e10cSrcweir const basegfx::B2DHomMatrix& rTransform, 915cdf0e10cSrcweir const GraphicObject& rGraphicObject) 916cdf0e10cSrcweir : BufferedDecompositionPrimitive2D(), 917cdf0e10cSrcweir maTransform(rTransform), 918cdf0e10cSrcweir maGraphicObject(rGraphicObject), 919cdf0e10cSrcweir maGraphicAttr() 920cdf0e10cSrcweir { 921cdf0e10cSrcweir } 922cdf0e10cSrcweir 923cdf0e10cSrcweir bool GraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 924cdf0e10cSrcweir { 925cdf0e10cSrcweir if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 926cdf0e10cSrcweir { 927cdf0e10cSrcweir const GraphicPrimitive2D& rCompare = (GraphicPrimitive2D&)rPrimitive; 928cdf0e10cSrcweir 929cdf0e10cSrcweir return (getTransform() == rCompare.getTransform() 930cdf0e10cSrcweir && getGraphicObject() == rCompare.getGraphicObject() 931cdf0e10cSrcweir && getGraphicAttr() == rCompare.getGraphicAttr()); 932cdf0e10cSrcweir } 933cdf0e10cSrcweir 934cdf0e10cSrcweir return false; 935cdf0e10cSrcweir } 936cdf0e10cSrcweir 937cdf0e10cSrcweir basegfx::B2DRange GraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const 938cdf0e10cSrcweir { 939cdf0e10cSrcweir basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); 940cdf0e10cSrcweir aRetval.transform(getTransform()); 941cdf0e10cSrcweir return aRetval; 942cdf0e10cSrcweir } 943cdf0e10cSrcweir 944cdf0e10cSrcweir // provide unique ID 945cdf0e10cSrcweir ImplPrimitrive2DIDBlock(GraphicPrimitive2D, PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D) 946cdf0e10cSrcweir 947cdf0e10cSrcweir } // end of namespace primitive2d 948cdf0e10cSrcweir } // end of namespace drawinglayer 949cdf0e10cSrcweir 950cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 951cdf0e10cSrcweir // eof 952