1*4665f8d3SArmin Le Grand /************************************************************** 2*4665f8d3SArmin Le Grand * 3*4665f8d3SArmin Le Grand * Licensed to the Apache Software Foundation (ASF) under one 4*4665f8d3SArmin Le Grand * or more contributor license agreements. See the NOTICE file 5*4665f8d3SArmin Le Grand * distributed with this work for additional information 6*4665f8d3SArmin Le Grand * regarding copyright ownership. The ASF licenses this file 7*4665f8d3SArmin Le Grand * to you under the Apache License, Version 2.0 (the 8*4665f8d3SArmin Le Grand * "License"); you may not use this file except in compliance 9*4665f8d3SArmin Le Grand * with the License. You may obtain a copy of the License at 10*4665f8d3SArmin Le Grand * 11*4665f8d3SArmin Le Grand * http://www.apache.org/licenses/LICENSE-2.0 12*4665f8d3SArmin Le Grand * 13*4665f8d3SArmin Le Grand * Unless required by applicable law or agreed to in writing, 14*4665f8d3SArmin Le Grand * software distributed under the License is distributed on an 15*4665f8d3SArmin Le Grand * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*4665f8d3SArmin Le Grand * KIND, either express or implied. See the License for the 17*4665f8d3SArmin Le Grand * specific language governing permissions and limitations 18*4665f8d3SArmin Le Grand * under the License. 19*4665f8d3SArmin Le Grand * 20*4665f8d3SArmin Le Grand *************************************************************/ 21*4665f8d3SArmin Le Grand 22*4665f8d3SArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove 23*4665f8d3SArmin Le Grand #include "precompiled_vcl.hxx" 24*4665f8d3SArmin Le Grand 25*4665f8d3SArmin Le Grand #include <vcl/gdimetafiletools.hxx> 26*4665f8d3SArmin Le Grand #include <vcl/metaact.hxx> 27*4665f8d3SArmin Le Grand #include <basegfx/polygon/b2dpolygonclipper.hxx> 28*4665f8d3SArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx> 29*4665f8d3SArmin Le Grand #include <basegfx/polygon/b2dpolypolygontools.hxx> 30*4665f8d3SArmin Le Grand #include <basegfx/polygon/b2dpolygontools.hxx> 31*4665f8d3SArmin Le Grand #include <vcl/virdev.hxx> 32*4665f8d3SArmin Le Grand #include <vcl/svapp.hxx> 33*4665f8d3SArmin Le Grand #include <vcl/graphictools.hxx> 34*4665f8d3SArmin Le Grand 35*4665f8d3SArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 36*4665f8d3SArmin Le Grand // helpers 37*4665f8d3SArmin Le Grand 38*4665f8d3SArmin Le Grand namespace 39*4665f8d3SArmin Le Grand { 40*4665f8d3SArmin Le Grand bool handleGeometricContent( 41*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon& rClip, 42*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon& rSource, 43*4665f8d3SArmin Le Grand GDIMetaFile& rTarget, 44*4665f8d3SArmin Le Grand bool bStroke) 45*4665f8d3SArmin Le Grand { 46*4665f8d3SArmin Le Grand if(rSource.count() && rClip.count()) 47*4665f8d3SArmin Le Grand { 48*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon aResult( 49*4665f8d3SArmin Le Grand basegfx::tools::clipPolyPolygonOnPolyPolygon( 50*4665f8d3SArmin Le Grand rSource, 51*4665f8d3SArmin Le Grand rClip, 52*4665f8d3SArmin Le Grand true, // inside 53*4665f8d3SArmin Le Grand bStroke)); 54*4665f8d3SArmin Le Grand 55*4665f8d3SArmin Le Grand if(aResult.count()) 56*4665f8d3SArmin Le Grand { 57*4665f8d3SArmin Le Grand if(aResult == rSource) 58*4665f8d3SArmin Le Grand { 59*4665f8d3SArmin Le Grand // not clipped, but inside. Add original 60*4665f8d3SArmin Le Grand return false; 61*4665f8d3SArmin Le Grand } 62*4665f8d3SArmin Le Grand else 63*4665f8d3SArmin Le Grand { 64*4665f8d3SArmin Le Grand // add clipped geometry 65*4665f8d3SArmin Le Grand if(bStroke) 66*4665f8d3SArmin Le Grand { 67*4665f8d3SArmin Le Grand for(sal_uInt32 a(0); a < aResult.count(); a++) 68*4665f8d3SArmin Le Grand { 69*4665f8d3SArmin Le Grand rTarget.AddAction( 70*4665f8d3SArmin Le Grand new MetaPolyLineAction( 71*4665f8d3SArmin Le Grand Polygon(aResult.getB2DPolygon(a)))); 72*4665f8d3SArmin Le Grand } 73*4665f8d3SArmin Le Grand } 74*4665f8d3SArmin Le Grand else 75*4665f8d3SArmin Le Grand { 76*4665f8d3SArmin Le Grand rTarget.AddAction( 77*4665f8d3SArmin Le Grand new MetaPolyPolygonAction( 78*4665f8d3SArmin Le Grand PolyPolygon(aResult))); 79*4665f8d3SArmin Le Grand } 80*4665f8d3SArmin Le Grand } 81*4665f8d3SArmin Le Grand } 82*4665f8d3SArmin Le Grand } 83*4665f8d3SArmin Le Grand 84*4665f8d3SArmin Le Grand return true; 85*4665f8d3SArmin Le Grand } 86*4665f8d3SArmin Le Grand 87*4665f8d3SArmin Le Grand bool handleGradientContent( 88*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon& rClip, 89*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon& rSource, 90*4665f8d3SArmin Le Grand const Gradient& rGradient, 91*4665f8d3SArmin Le Grand GDIMetaFile& rTarget) 92*4665f8d3SArmin Le Grand { 93*4665f8d3SArmin Le Grand if(rSource.count() && rClip.count()) 94*4665f8d3SArmin Le Grand { 95*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon aResult( 96*4665f8d3SArmin Le Grand basegfx::tools::clipPolyPolygonOnPolyPolygon( 97*4665f8d3SArmin Le Grand rSource, 98*4665f8d3SArmin Le Grand rClip, 99*4665f8d3SArmin Le Grand true, // inside 100*4665f8d3SArmin Le Grand false)); // stroke 101*4665f8d3SArmin Le Grand 102*4665f8d3SArmin Le Grand if(aResult.count()) 103*4665f8d3SArmin Le Grand { 104*4665f8d3SArmin Le Grand if(aResult == rSource) 105*4665f8d3SArmin Le Grand { 106*4665f8d3SArmin Le Grand // not clipped, but inside. Add original 107*4665f8d3SArmin Le Grand return false; 108*4665f8d3SArmin Le Grand } 109*4665f8d3SArmin Le Grand else 110*4665f8d3SArmin Le Grand { 111*4665f8d3SArmin Le Grand // add clipped geometry 112*4665f8d3SArmin Le Grand rTarget.AddAction( 113*4665f8d3SArmin Le Grand new MetaGradientExAction( 114*4665f8d3SArmin Le Grand PolyPolygon(aResult), 115*4665f8d3SArmin Le Grand rGradient)); 116*4665f8d3SArmin Le Grand } 117*4665f8d3SArmin Le Grand } 118*4665f8d3SArmin Le Grand } 119*4665f8d3SArmin Le Grand 120*4665f8d3SArmin Le Grand return true; 121*4665f8d3SArmin Le Grand } 122*4665f8d3SArmin Le Grand 123*4665f8d3SArmin Le Grand bool handleBitmapContent( 124*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon& rClip, 125*4665f8d3SArmin Le Grand const Point& rPoint, 126*4665f8d3SArmin Le Grand const Size& rSize, 127*4665f8d3SArmin Le Grand const BitmapEx& rBitmapEx, 128*4665f8d3SArmin Le Grand GDIMetaFile& rTarget) 129*4665f8d3SArmin Le Grand { 130*4665f8d3SArmin Le Grand if(!rSize.Width() || !rSize.Height() || rBitmapEx.IsEmpty()) 131*4665f8d3SArmin Le Grand { 132*4665f8d3SArmin Le Grand // bitmap or size is empty 133*4665f8d3SArmin Le Grand return true; 134*4665f8d3SArmin Le Grand } 135*4665f8d3SArmin Le Grand 136*4665f8d3SArmin Le Grand const basegfx::B2DRange aLogicBitmapRange( 137*4665f8d3SArmin Le Grand rPoint.X(), rPoint.Y(), 138*4665f8d3SArmin Le Grand rPoint.X() + rSize.Width(), rPoint.Y() + rSize.Height()); 139*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon aClipOfBitmap( 140*4665f8d3SArmin Le Grand basegfx::tools::clipPolyPolygonOnRange( 141*4665f8d3SArmin Le Grand rClip, 142*4665f8d3SArmin Le Grand aLogicBitmapRange, 143*4665f8d3SArmin Le Grand true, 144*4665f8d3SArmin Le Grand false)); // stroke 145*4665f8d3SArmin Le Grand 146*4665f8d3SArmin Le Grand if(!aClipOfBitmap.count()) 147*4665f8d3SArmin Le Grand { 148*4665f8d3SArmin Le Grand // outside clip region 149*4665f8d3SArmin Le Grand return true; 150*4665f8d3SArmin Le Grand } 151*4665f8d3SArmin Le Grand 152*4665f8d3SArmin Le Grand // inside or overlapping. Use area to find out if it is completely 153*4665f8d3SArmin Le Grand // covering (inside) or overlapping 154*4665f8d3SArmin Le Grand const double fClipArea(basegfx::tools::getArea(aClipOfBitmap)); 155*4665f8d3SArmin Le Grand const double fBitmapArea( 156*4665f8d3SArmin Le Grand aLogicBitmapRange.getWidth() * aLogicBitmapRange.getWidth() + 157*4665f8d3SArmin Le Grand aLogicBitmapRange.getHeight() * aLogicBitmapRange.getHeight()); 158*4665f8d3SArmin Le Grand const double fFactor(fClipArea / fBitmapArea); 159*4665f8d3SArmin Le Grand 160*4665f8d3SArmin Le Grand if(basegfx::fTools::more(fFactor, 1.0 - 0.001)) 161*4665f8d3SArmin Le Grand { 162*4665f8d3SArmin Le Grand // completely covering (with 0.1% tolerance) 163*4665f8d3SArmin Le Grand return false; 164*4665f8d3SArmin Le Grand } 165*4665f8d3SArmin Le Grand 166*4665f8d3SArmin Le Grand // needs clipping (with 0.1% tolerance). Prepare VirtualDevice 167*4665f8d3SArmin Le Grand // in pixel mode for alpha channel painting (black is transparent, 168*4665f8d3SArmin Le Grand // white to paint 100% opacity) 169*4665f8d3SArmin Le Grand const Size aSizePixel(rBitmapEx.GetSizePixel()); 170*4665f8d3SArmin Le Grand VirtualDevice aVDev; 171*4665f8d3SArmin Le Grand 172*4665f8d3SArmin Le Grand aVDev.SetOutputSizePixel(aSizePixel); 173*4665f8d3SArmin Le Grand aVDev.EnableMapMode(false); 174*4665f8d3SArmin Le Grand aVDev.SetFillColor(COL_WHITE); 175*4665f8d3SArmin Le Grand aVDev.SetLineColor(); 176*4665f8d3SArmin Le Grand 177*4665f8d3SArmin Le Grand if(rBitmapEx.IsTransparent()) 178*4665f8d3SArmin Le Grand { 179*4665f8d3SArmin Le Grand // use given alpha channel 180*4665f8d3SArmin Le Grand aVDev.DrawBitmap(Point(0, 0), rBitmapEx.GetAlpha().GetBitmap()); 181*4665f8d3SArmin Le Grand } 182*4665f8d3SArmin Le Grand else 183*4665f8d3SArmin Le Grand { 184*4665f8d3SArmin Le Grand // reset alpha channel 185*4665f8d3SArmin Le Grand aVDev.SetBackground(Wallpaper(Color(COL_BLACK))); 186*4665f8d3SArmin Le Grand aVDev.Erase(); 187*4665f8d3SArmin Le Grand } 188*4665f8d3SArmin Le Grand 189*4665f8d3SArmin Le Grand // transform polygon from clipping to pixel coordinates 190*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon aPixelPoly(aClipOfBitmap); 191*4665f8d3SArmin Le Grand basegfx::B2DHomMatrix aTransform; 192*4665f8d3SArmin Le Grand 193*4665f8d3SArmin Le Grand aTransform.translate(-aLogicBitmapRange.getMinX(), -aLogicBitmapRange.getMinY()); 194*4665f8d3SArmin Le Grand aTransform.scale( 195*4665f8d3SArmin Le Grand static_cast< double >(aSizePixel.Width()) / aLogicBitmapRange.getWidth(), 196*4665f8d3SArmin Le Grand static_cast< double >(aSizePixel.Height()) / aLogicBitmapRange.getHeight()); 197*4665f8d3SArmin Le Grand aPixelPoly.transform(aTransform); 198*4665f8d3SArmin Le Grand 199*4665f8d3SArmin Le Grand // to fill the non-covered parts, use the Xor fill rule of 200*4665f8d3SArmin Le Grand // PolyPolygon painting. Start with a all-covering polygon and 201*4665f8d3SArmin Le Grand // add the clip polygon one 202*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon aInvertPixelPoly; 203*4665f8d3SArmin Le Grand 204*4665f8d3SArmin Le Grand aInvertPixelPoly.append( 205*4665f8d3SArmin Le Grand basegfx::tools::createPolygonFromRect( 206*4665f8d3SArmin Le Grand basegfx::B2DRange( 207*4665f8d3SArmin Le Grand 0.0, 0.0, 208*4665f8d3SArmin Le Grand aSizePixel.Width(), aSizePixel.Height()))); 209*4665f8d3SArmin Le Grand aInvertPixelPoly.append(aPixelPoly); 210*4665f8d3SArmin Le Grand 211*4665f8d3SArmin Le Grand // paint as alpha 212*4665f8d3SArmin Le Grand aVDev.DrawPolyPolygon(aInvertPixelPoly); 213*4665f8d3SArmin Le Grand 214*4665f8d3SArmin Le Grand // get created alpha mask and set defaults 215*4665f8d3SArmin Le Grand AlphaMask aAlpha( 216*4665f8d3SArmin Le Grand aVDev.GetBitmap( 217*4665f8d3SArmin Le Grand Point(0, 0), 218*4665f8d3SArmin Le Grand aSizePixel)); 219*4665f8d3SArmin Le Grand 220*4665f8d3SArmin Le Grand aAlpha.SetPrefSize(rBitmapEx.GetPrefSize()); 221*4665f8d3SArmin Le Grand aAlpha.SetPrefMapMode(rBitmapEx.GetPrefMapMode()); 222*4665f8d3SArmin Le Grand 223*4665f8d3SArmin Le Grand // add new action replacing the old one 224*4665f8d3SArmin Le Grand rTarget.AddAction( 225*4665f8d3SArmin Le Grand new MetaBmpExScaleAction( 226*4665f8d3SArmin Le Grand Point( 227*4665f8d3SArmin Le Grand basegfx::fround(aLogicBitmapRange.getMinX()), 228*4665f8d3SArmin Le Grand basegfx::fround(aLogicBitmapRange.getMinY())), 229*4665f8d3SArmin Le Grand Size( 230*4665f8d3SArmin Le Grand basegfx::fround(aLogicBitmapRange.getWidth()), 231*4665f8d3SArmin Le Grand basegfx::fround(aLogicBitmapRange.getHeight())), 232*4665f8d3SArmin Le Grand BitmapEx(rBitmapEx.GetBitmap(), aAlpha))); 233*4665f8d3SArmin Le Grand 234*4665f8d3SArmin Le Grand return true; 235*4665f8d3SArmin Le Grand } 236*4665f8d3SArmin Le Grand 237*4665f8d3SArmin Le Grand void addSvtGraphicStroke(const SvtGraphicStroke& rStroke, GDIMetaFile& rTarget) 238*4665f8d3SArmin Le Grand { 239*4665f8d3SArmin Le Grand // write SvtGraphicFill 240*4665f8d3SArmin Le Grand SvMemoryStream aMemStm; 241*4665f8d3SArmin Le Grand aMemStm << rStroke; 242*4665f8d3SArmin Le Grand rTarget.AddAction( 243*4665f8d3SArmin Le Grand new MetaCommentAction( 244*4665f8d3SArmin Le Grand "XPATHSTROKE_SEQ_BEGIN", 245*4665f8d3SArmin Le Grand 0, 246*4665f8d3SArmin Le Grand static_cast< const sal_uInt8* >(aMemStm.GetData()), 247*4665f8d3SArmin Le Grand aMemStm.Seek(STREAM_SEEK_TO_END))); 248*4665f8d3SArmin Le Grand } 249*4665f8d3SArmin Le Grand 250*4665f8d3SArmin Le Grand void addSvtGraphicFill(const SvtGraphicFill &rFilling, GDIMetaFile& rTarget) 251*4665f8d3SArmin Le Grand { 252*4665f8d3SArmin Le Grand // write SvtGraphicFill 253*4665f8d3SArmin Le Grand SvMemoryStream aMemStm; 254*4665f8d3SArmin Le Grand aMemStm << rFilling; 255*4665f8d3SArmin Le Grand rTarget.AddAction( 256*4665f8d3SArmin Le Grand new MetaCommentAction( 257*4665f8d3SArmin Le Grand "XPATHFILL_SEQ_BEGIN", 258*4665f8d3SArmin Le Grand 0, 259*4665f8d3SArmin Le Grand static_cast< const sal_uInt8* >(aMemStm.GetData()), 260*4665f8d3SArmin Le Grand aMemStm.Seek(STREAM_SEEK_TO_END))); 261*4665f8d3SArmin Le Grand } 262*4665f8d3SArmin Le Grand } // end of anonymous namespace 263*4665f8d3SArmin Le Grand 264*4665f8d3SArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 265*4665f8d3SArmin Le Grand // #121267# Tooling to internally clip geometry against internal clip regions 266*4665f8d3SArmin Le Grand 267*4665f8d3SArmin Le Grand void clipMetafileContentAgainstOwnRegions(GDIMetaFile& rSource) 268*4665f8d3SArmin Le Grand { 269*4665f8d3SArmin Le Grand const sal_uLong nObjCount(rSource.GetActionCount()); 270*4665f8d3SArmin Le Grand 271*4665f8d3SArmin Le Grand if(!nObjCount) 272*4665f8d3SArmin Le Grand { 273*4665f8d3SArmin Le Grand return; 274*4665f8d3SArmin Le Grand } 275*4665f8d3SArmin Le Grand 276*4665f8d3SArmin Le Grand // prepare target data container and push/pop stack data 277*4665f8d3SArmin Le Grand GDIMetaFile aTarget; 278*4665f8d3SArmin Le Grand bool bChanged(false); 279*4665f8d3SArmin Le Grand std::vector< basegfx::B2DPolyPolygon > aClips; 280*4665f8d3SArmin Le Grand std::vector< sal_uInt16 > aPushFlags; 281*4665f8d3SArmin Le Grand std::vector< MapMode > aMapModes; 282*4665f8d3SArmin Le Grand 283*4665f8d3SArmin Le Grand // start with empty region 284*4665f8d3SArmin Le Grand aClips.push_back(basegfx::B2DPolyPolygon()); 285*4665f8d3SArmin Le Grand 286*4665f8d3SArmin Le Grand // start with default MapMode (MAP_PIXEL) 287*4665f8d3SArmin Le Grand aMapModes.push_back(MapMode()); 288*4665f8d3SArmin Le Grand 289*4665f8d3SArmin Le Grand for(sal_uLong i(0); i < nObjCount; ++i) 290*4665f8d3SArmin Le Grand { 291*4665f8d3SArmin Le Grand const MetaAction* pAction(rSource.GetAction(i)); 292*4665f8d3SArmin Le Grand const sal_uInt16 nType(pAction->GetType()); 293*4665f8d3SArmin Le Grand bool bDone(false); 294*4665f8d3SArmin Le Grand 295*4665f8d3SArmin Le Grand // basic operation takes care of clipregion actions (four) and push/pop of these 296*4665f8d3SArmin Le Grand // to steer the currently set clip region. There *is* an active 297*4665f8d3SArmin Le Grand // clip region when (aClips.size() && aClips.back().count()), see 298*4665f8d3SArmin Le Grand // below 299*4665f8d3SArmin Le Grand switch(nType) 300*4665f8d3SArmin Le Grand { 301*4665f8d3SArmin Le Grand case META_CLIPREGION_ACTION : 302*4665f8d3SArmin Le Grand { 303*4665f8d3SArmin Le Grand const MetaClipRegionAction* pA = static_cast< const MetaClipRegionAction* >(pAction); 304*4665f8d3SArmin Le Grand 305*4665f8d3SArmin Le Grand if(pA->IsClipping()) 306*4665f8d3SArmin Le Grand { 307*4665f8d3SArmin Le Grand const Region& rRegion = pA->GetRegion(); 308*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon aNewClip(rRegion.GetAsB2DPolyPolygon()); 309*4665f8d3SArmin Le Grand 310*4665f8d3SArmin Le Grand aClips.back() = aNewClip; 311*4665f8d3SArmin Le Grand } 312*4665f8d3SArmin Le Grand else 313*4665f8d3SArmin Le Grand { 314*4665f8d3SArmin Le Grand aClips.back() = basegfx::B2DPolyPolygon(); 315*4665f8d3SArmin Le Grand } 316*4665f8d3SArmin Le Grand 317*4665f8d3SArmin Le Grand break; 318*4665f8d3SArmin Le Grand } 319*4665f8d3SArmin Le Grand 320*4665f8d3SArmin Le Grand case META_ISECTRECTCLIPREGION_ACTION : 321*4665f8d3SArmin Le Grand { 322*4665f8d3SArmin Le Grand const MetaISectRectClipRegionAction* pA = static_cast< const MetaISectRectClipRegionAction* >(pAction); 323*4665f8d3SArmin Le Grand const Rectangle& rRect = pA->GetRect(); 324*4665f8d3SArmin Le Grand 325*4665f8d3SArmin Le Grand if(!rRect.IsEmpty() && aClips.size() && aClips.back().count()) 326*4665f8d3SArmin Le Grand { 327*4665f8d3SArmin Le Grand const basegfx::B2DRange aClipRange( 328*4665f8d3SArmin Le Grand rRect.Left(), rRect.Top(), 329*4665f8d3SArmin Le Grand rRect.Right(), rRect.Bottom()); 330*4665f8d3SArmin Le Grand 331*4665f8d3SArmin Le Grand aClips.back() = basegfx::tools::clipPolyPolygonOnRange( 332*4665f8d3SArmin Le Grand aClips.back(), 333*4665f8d3SArmin Le Grand aClipRange, 334*4665f8d3SArmin Le Grand true, // inside 335*4665f8d3SArmin Le Grand false); // stroke 336*4665f8d3SArmin Le Grand } 337*4665f8d3SArmin Le Grand break; 338*4665f8d3SArmin Le Grand } 339*4665f8d3SArmin Le Grand 340*4665f8d3SArmin Le Grand case META_ISECTREGIONCLIPREGION_ACTION : 341*4665f8d3SArmin Le Grand { 342*4665f8d3SArmin Le Grand const MetaISectRegionClipRegionAction* pA = static_cast< const MetaISectRegionClipRegionAction* >(pAction); 343*4665f8d3SArmin Le Grand const Region& rRegion = pA->GetRegion(); 344*4665f8d3SArmin Le Grand 345*4665f8d3SArmin Le Grand if(!rRegion.IsEmpty() && aClips.size() && aClips.back().count()) 346*4665f8d3SArmin Le Grand { 347*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon aNewClip(rRegion.GetAsB2DPolyPolygon()); 348*4665f8d3SArmin Le Grand 349*4665f8d3SArmin Le Grand aClips.back() = basegfx::tools::clipPolyPolygonOnPolyPolygon( 350*4665f8d3SArmin Le Grand aClips.back(), 351*4665f8d3SArmin Le Grand aNewClip, 352*4665f8d3SArmin Le Grand true, // inside 353*4665f8d3SArmin Le Grand false); // stroke 354*4665f8d3SArmin Le Grand } 355*4665f8d3SArmin Le Grand break; 356*4665f8d3SArmin Le Grand } 357*4665f8d3SArmin Le Grand 358*4665f8d3SArmin Le Grand case META_MOVECLIPREGION_ACTION : 359*4665f8d3SArmin Le Grand { 360*4665f8d3SArmin Le Grand const MetaMoveClipRegionAction* pA = static_cast< const MetaMoveClipRegionAction* >(pAction); 361*4665f8d3SArmin Le Grand const long aHorMove(pA->GetHorzMove()); 362*4665f8d3SArmin Le Grand const long aVerMove(pA->GetVertMove()); 363*4665f8d3SArmin Le Grand 364*4665f8d3SArmin Le Grand if((aHorMove || aVerMove) && aClips.size() && aClips.back().count()) 365*4665f8d3SArmin Le Grand { 366*4665f8d3SArmin Le Grand aClips.back().transform( 367*4665f8d3SArmin Le Grand basegfx::tools::createTranslateB2DHomMatrix( 368*4665f8d3SArmin Le Grand aHorMove, 369*4665f8d3SArmin Le Grand aVerMove)); 370*4665f8d3SArmin Le Grand } 371*4665f8d3SArmin Le Grand break; 372*4665f8d3SArmin Le Grand } 373*4665f8d3SArmin Le Grand 374*4665f8d3SArmin Le Grand case META_PUSH_ACTION : 375*4665f8d3SArmin Le Grand { 376*4665f8d3SArmin Le Grand const MetaPushAction* pA = static_cast< const MetaPushAction* >(pAction); 377*4665f8d3SArmin Le Grand const sal_uInt16 nFlags(pA->GetFlags()); 378*4665f8d3SArmin Le Grand 379*4665f8d3SArmin Le Grand aPushFlags.push_back(nFlags); 380*4665f8d3SArmin Le Grand 381*4665f8d3SArmin Le Grand if(nFlags & PUSH_CLIPREGION) 382*4665f8d3SArmin Le Grand { 383*4665f8d3SArmin Le Grand aClips.push_back(aClips.back()); 384*4665f8d3SArmin Le Grand } 385*4665f8d3SArmin Le Grand 386*4665f8d3SArmin Le Grand if(nFlags & PUSH_MAPMODE) 387*4665f8d3SArmin Le Grand { 388*4665f8d3SArmin Le Grand aMapModes.push_back(aMapModes.back()); 389*4665f8d3SArmin Le Grand } 390*4665f8d3SArmin Le Grand break; 391*4665f8d3SArmin Le Grand } 392*4665f8d3SArmin Le Grand 393*4665f8d3SArmin Le Grand case META_POP_ACTION : 394*4665f8d3SArmin Le Grand { 395*4665f8d3SArmin Le Grand const MetaPopAction* pA = static_cast< const MetaPopAction* >(pAction); 396*4665f8d3SArmin Le Grand 397*4665f8d3SArmin Le Grand if(aPushFlags.size()) 398*4665f8d3SArmin Le Grand { 399*4665f8d3SArmin Le Grand const sal_uInt16 nFlags(aPushFlags.back()); 400*4665f8d3SArmin Le Grand aPushFlags.pop_back(); 401*4665f8d3SArmin Le Grand 402*4665f8d3SArmin Le Grand if(nFlags & PUSH_CLIPREGION) 403*4665f8d3SArmin Le Grand { 404*4665f8d3SArmin Le Grand if(aClips.size() > 1) 405*4665f8d3SArmin Le Grand { 406*4665f8d3SArmin Le Grand aClips.pop_back(); 407*4665f8d3SArmin Le Grand } 408*4665f8d3SArmin Le Grand else 409*4665f8d3SArmin Le Grand { 410*4665f8d3SArmin Le Grand OSL_ENSURE(false, "Wrong POP() in ClipRegions (!)"); 411*4665f8d3SArmin Le Grand } 412*4665f8d3SArmin Le Grand } 413*4665f8d3SArmin Le Grand 414*4665f8d3SArmin Le Grand if(nFlags & PUSH_MAPMODE) 415*4665f8d3SArmin Le Grand { 416*4665f8d3SArmin Le Grand if(aMapModes.size() > 1) 417*4665f8d3SArmin Le Grand { 418*4665f8d3SArmin Le Grand aMapModes.pop_back(); 419*4665f8d3SArmin Le Grand } 420*4665f8d3SArmin Le Grand else 421*4665f8d3SArmin Le Grand { 422*4665f8d3SArmin Le Grand OSL_ENSURE(false, "Wrong POP() in MapModes (!)"); 423*4665f8d3SArmin Le Grand } 424*4665f8d3SArmin Le Grand } 425*4665f8d3SArmin Le Grand } 426*4665f8d3SArmin Le Grand else 427*4665f8d3SArmin Le Grand { 428*4665f8d3SArmin Le Grand OSL_ENSURE(false, "Invalid pop() without push() (!)"); 429*4665f8d3SArmin Le Grand } 430*4665f8d3SArmin Le Grand 431*4665f8d3SArmin Le Grand break; 432*4665f8d3SArmin Le Grand } 433*4665f8d3SArmin Le Grand 434*4665f8d3SArmin Le Grand case META_MAPMODE_ACTION : 435*4665f8d3SArmin Le Grand { 436*4665f8d3SArmin Le Grand const MetaMapModeAction* pA = static_cast< const MetaMapModeAction* >(pAction); 437*4665f8d3SArmin Le Grand 438*4665f8d3SArmin Le Grand aMapModes.back() = pA->GetMapMode(); 439*4665f8d3SArmin Le Grand break; 440*4665f8d3SArmin Le Grand } 441*4665f8d3SArmin Le Grand 442*4665f8d3SArmin Le Grand default: 443*4665f8d3SArmin Le Grand { 444*4665f8d3SArmin Le Grand break; 445*4665f8d3SArmin Le Grand } 446*4665f8d3SArmin Le Grand } 447*4665f8d3SArmin Le Grand 448*4665f8d3SArmin Le Grand // this area contains all actions which could potentially be clipped. Since 449*4665f8d3SArmin Le Grand // this tooling is only a fallback (see comments in header), only the needed 450*4665f8d3SArmin Le Grand // actions will be implemented. Extend using the pattern for the already 451*4665f8d3SArmin Le Grand // implemented actions. 452*4665f8d3SArmin Le Grand if(aClips.size() && aClips.back().count()) 453*4665f8d3SArmin Le Grand { 454*4665f8d3SArmin Le Grand switch(nType) 455*4665f8d3SArmin Le Grand { 456*4665f8d3SArmin Le Grand // 457*4665f8d3SArmin Le Grand // pixel actions, just check on inside 458*4665f8d3SArmin Le Grand // 459*4665f8d3SArmin Le Grand case META_PIXEL_ACTION : 460*4665f8d3SArmin Le Grand { 461*4665f8d3SArmin Le Grand const MetaPixelAction* pA = static_cast< const MetaPixelAction* >(pAction); 462*4665f8d3SArmin Le Grand const Point& rPoint = pA->GetPoint(); 463*4665f8d3SArmin Le Grand 464*4665f8d3SArmin Le Grand if(!basegfx::tools::isInside( 465*4665f8d3SArmin Le Grand aClips.back(), 466*4665f8d3SArmin Le Grand basegfx::B2DPoint(rPoint.X(), rPoint.Y()))) 467*4665f8d3SArmin Le Grand { 468*4665f8d3SArmin Le Grand // when not inside, do not add original 469*4665f8d3SArmin Le Grand bDone = true; 470*4665f8d3SArmin Le Grand } 471*4665f8d3SArmin Le Grand break; 472*4665f8d3SArmin Le Grand } 473*4665f8d3SArmin Le Grand 474*4665f8d3SArmin Le Grand case META_POINT_ACTION : 475*4665f8d3SArmin Le Grand { 476*4665f8d3SArmin Le Grand const MetaPointAction* pA = static_cast< const MetaPointAction* >(pAction); 477*4665f8d3SArmin Le Grand const Point& rPoint = pA->GetPoint(); 478*4665f8d3SArmin Le Grand 479*4665f8d3SArmin Le Grand if(!basegfx::tools::isInside( 480*4665f8d3SArmin Le Grand aClips.back(), 481*4665f8d3SArmin Le Grand basegfx::B2DPoint(rPoint.X(), rPoint.Y()))) 482*4665f8d3SArmin Le Grand { 483*4665f8d3SArmin Le Grand // when not inside, do not add original 484*4665f8d3SArmin Le Grand bDone = true; 485*4665f8d3SArmin Le Grand } 486*4665f8d3SArmin Le Grand break; 487*4665f8d3SArmin Le Grand } 488*4665f8d3SArmin Le Grand 489*4665f8d3SArmin Le Grand // 490*4665f8d3SArmin Le Grand // geometry actions 491*4665f8d3SArmin Le Grand // 492*4665f8d3SArmin Le Grand case META_LINE_ACTION : 493*4665f8d3SArmin Le Grand { 494*4665f8d3SArmin Le Grand const MetaLineAction* pA = static_cast< const MetaLineAction* >(pAction); 495*4665f8d3SArmin Le Grand const Point& rStart(pA->GetStartPoint()); 496*4665f8d3SArmin Le Grand const Point& rEnd(pA->GetEndPoint()); 497*4665f8d3SArmin Le Grand basegfx::B2DPolygon aLine; 498*4665f8d3SArmin Le Grand 499*4665f8d3SArmin Le Grand aLine.append(basegfx::B2DPoint(rStart.X(), rStart.Y())); 500*4665f8d3SArmin Le Grand aLine.append(basegfx::B2DPoint(rEnd.X(), rEnd.Y())); 501*4665f8d3SArmin Le Grand 502*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 503*4665f8d3SArmin Le Grand aClips.back(), 504*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon(aLine), 505*4665f8d3SArmin Le Grand aTarget, 506*4665f8d3SArmin Le Grand true); // stroke 507*4665f8d3SArmin Le Grand break; 508*4665f8d3SArmin Le Grand } 509*4665f8d3SArmin Le Grand 510*4665f8d3SArmin Le Grand case META_RECT_ACTION : 511*4665f8d3SArmin Le Grand { 512*4665f8d3SArmin Le Grand const MetaRectAction* pA = static_cast< const MetaRectAction* >(pAction); 513*4665f8d3SArmin Le Grand const Rectangle& rRect = pA->GetRect(); 514*4665f8d3SArmin Le Grand 515*4665f8d3SArmin Le Grand if(rRect.IsEmpty()) 516*4665f8d3SArmin Le Grand { 517*4665f8d3SArmin Le Grand bDone = true; 518*4665f8d3SArmin Le Grand } 519*4665f8d3SArmin Le Grand else 520*4665f8d3SArmin Le Grand { 521*4665f8d3SArmin Le Grand 522*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 523*4665f8d3SArmin Le Grand aClips.back(), 524*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon( 525*4665f8d3SArmin Le Grand basegfx::tools::createPolygonFromRect( 526*4665f8d3SArmin Le Grand basegfx::B2DRange( 527*4665f8d3SArmin Le Grand rRect.Left(), rRect.Top(), 528*4665f8d3SArmin Le Grand rRect.Right(), rRect.Bottom()))), 529*4665f8d3SArmin Le Grand aTarget, 530*4665f8d3SArmin Le Grand false); // stroke 531*4665f8d3SArmin Le Grand } 532*4665f8d3SArmin Le Grand break; 533*4665f8d3SArmin Le Grand } 534*4665f8d3SArmin Le Grand 535*4665f8d3SArmin Le Grand case META_ROUNDRECT_ACTION : 536*4665f8d3SArmin Le Grand { 537*4665f8d3SArmin Le Grand const MetaRoundRectAction* pA = static_cast< const MetaRoundRectAction* >(pAction); 538*4665f8d3SArmin Le Grand const Rectangle& rRect = pA->GetRect(); 539*4665f8d3SArmin Le Grand 540*4665f8d3SArmin Le Grand if(rRect.IsEmpty()) 541*4665f8d3SArmin Le Grand { 542*4665f8d3SArmin Le Grand bDone = true; 543*4665f8d3SArmin Le Grand } 544*4665f8d3SArmin Le Grand else 545*4665f8d3SArmin Le Grand { 546*4665f8d3SArmin Le Grand const sal_uInt32 nHor(pA->GetHorzRound()); 547*4665f8d3SArmin Le Grand const sal_uInt32 nVer(pA->GetVertRound()); 548*4665f8d3SArmin Le Grand const basegfx::B2DRange aRange(rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom()); 549*4665f8d3SArmin Le Grand basegfx::B2DPolygon aOutline; 550*4665f8d3SArmin Le Grand 551*4665f8d3SArmin Le Grand if(nHor || nVer) 552*4665f8d3SArmin Le Grand { 553*4665f8d3SArmin Le Grand double fRadiusX((nHor * 2.0) / (aRange.getWidth() > 0.0 ? aRange.getWidth() : 1.0)); 554*4665f8d3SArmin Le Grand double fRadiusY((nVer * 2.0) / (aRange.getHeight() > 0.0 ? aRange.getHeight() : 1.0)); 555*4665f8d3SArmin Le Grand fRadiusX = std::max(0.0, std::min(1.0, fRadiusX)); 556*4665f8d3SArmin Le Grand fRadiusY = std::max(0.0, std::min(1.0, fRadiusY)); 557*4665f8d3SArmin Le Grand 558*4665f8d3SArmin Le Grand aOutline = basegfx::tools::createPolygonFromRect(aRange, fRadiusX, fRadiusY); 559*4665f8d3SArmin Le Grand } 560*4665f8d3SArmin Le Grand else 561*4665f8d3SArmin Le Grand { 562*4665f8d3SArmin Le Grand aOutline = basegfx::tools::createPolygonFromRect(aRange); 563*4665f8d3SArmin Le Grand } 564*4665f8d3SArmin Le Grand 565*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 566*4665f8d3SArmin Le Grand aClips.back(), 567*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon(aOutline), 568*4665f8d3SArmin Le Grand aTarget, 569*4665f8d3SArmin Le Grand false); // stroke 570*4665f8d3SArmin Le Grand } 571*4665f8d3SArmin Le Grand break; 572*4665f8d3SArmin Le Grand } 573*4665f8d3SArmin Le Grand 574*4665f8d3SArmin Le Grand case META_ELLIPSE_ACTION : 575*4665f8d3SArmin Le Grand { 576*4665f8d3SArmin Le Grand const MetaEllipseAction* pA = static_cast< const MetaEllipseAction* >(pAction); 577*4665f8d3SArmin Le Grand const Rectangle& rRect = pA->GetRect(); 578*4665f8d3SArmin Le Grand 579*4665f8d3SArmin Le Grand if(rRect.IsEmpty()) 580*4665f8d3SArmin Le Grand { 581*4665f8d3SArmin Le Grand bDone = true; 582*4665f8d3SArmin Le Grand } 583*4665f8d3SArmin Le Grand else 584*4665f8d3SArmin Le Grand { 585*4665f8d3SArmin Le Grand const basegfx::B2DRange aRange(rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom()); 586*4665f8d3SArmin Le Grand 587*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 588*4665f8d3SArmin Le Grand aClips.back(), 589*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon( 590*4665f8d3SArmin Le Grand basegfx::tools::createPolygonFromEllipse( 591*4665f8d3SArmin Le Grand aRange.getCenter(), 592*4665f8d3SArmin Le Grand aRange.getWidth() * 0.5, 593*4665f8d3SArmin Le Grand aRange.getHeight() * 0.5)), 594*4665f8d3SArmin Le Grand aTarget, 595*4665f8d3SArmin Le Grand false); // stroke 596*4665f8d3SArmin Le Grand } 597*4665f8d3SArmin Le Grand break; 598*4665f8d3SArmin Le Grand } 599*4665f8d3SArmin Le Grand 600*4665f8d3SArmin Le Grand case META_ARC_ACTION : 601*4665f8d3SArmin Le Grand { 602*4665f8d3SArmin Le Grand const MetaArcAction* pA = static_cast< const MetaArcAction* >(pAction); 603*4665f8d3SArmin Le Grand const Rectangle& rRect = pA->GetRect(); 604*4665f8d3SArmin Le Grand 605*4665f8d3SArmin Le Grand if(rRect.IsEmpty()) 606*4665f8d3SArmin Le Grand { 607*4665f8d3SArmin Le Grand bDone = true; 608*4665f8d3SArmin Le Grand } 609*4665f8d3SArmin Le Grand else 610*4665f8d3SArmin Le Grand { 611*4665f8d3SArmin Le Grand const Polygon aToolsPoly( 612*4665f8d3SArmin Le Grand rRect, 613*4665f8d3SArmin Le Grand pA->GetStartPoint(), 614*4665f8d3SArmin Le Grand pA->GetEndPoint(), 615*4665f8d3SArmin Le Grand POLY_ARC); 616*4665f8d3SArmin Le Grand 617*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 618*4665f8d3SArmin Le Grand aClips.back(), 619*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon(aToolsPoly.getB2DPolygon()), 620*4665f8d3SArmin Le Grand aTarget, 621*4665f8d3SArmin Le Grand true); // stroke 622*4665f8d3SArmin Le Grand } 623*4665f8d3SArmin Le Grand break; 624*4665f8d3SArmin Le Grand } 625*4665f8d3SArmin Le Grand 626*4665f8d3SArmin Le Grand case META_PIE_ACTION : 627*4665f8d3SArmin Le Grand { 628*4665f8d3SArmin Le Grand const MetaPieAction* pA = static_cast< const MetaPieAction* >(pAction); 629*4665f8d3SArmin Le Grand const Rectangle& rRect = pA->GetRect(); 630*4665f8d3SArmin Le Grand 631*4665f8d3SArmin Le Grand if(rRect.IsEmpty()) 632*4665f8d3SArmin Le Grand { 633*4665f8d3SArmin Le Grand bDone = true; 634*4665f8d3SArmin Le Grand } 635*4665f8d3SArmin Le Grand else 636*4665f8d3SArmin Le Grand { 637*4665f8d3SArmin Le Grand const Polygon aToolsPoly( 638*4665f8d3SArmin Le Grand rRect, 639*4665f8d3SArmin Le Grand pA->GetStartPoint(), 640*4665f8d3SArmin Le Grand pA->GetEndPoint(), 641*4665f8d3SArmin Le Grand POLY_PIE); 642*4665f8d3SArmin Le Grand 643*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 644*4665f8d3SArmin Le Grand aClips.back(), 645*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon(aToolsPoly.getB2DPolygon()), 646*4665f8d3SArmin Le Grand aTarget, 647*4665f8d3SArmin Le Grand false); // stroke 648*4665f8d3SArmin Le Grand } 649*4665f8d3SArmin Le Grand break; 650*4665f8d3SArmin Le Grand } 651*4665f8d3SArmin Le Grand 652*4665f8d3SArmin Le Grand case META_CHORD_ACTION : 653*4665f8d3SArmin Le Grand { 654*4665f8d3SArmin Le Grand const MetaChordAction* pA = static_cast< const MetaChordAction* >(pAction); 655*4665f8d3SArmin Le Grand const Rectangle& rRect = pA->GetRect(); 656*4665f8d3SArmin Le Grand 657*4665f8d3SArmin Le Grand if(rRect.IsEmpty()) 658*4665f8d3SArmin Le Grand { 659*4665f8d3SArmin Le Grand bDone = true; 660*4665f8d3SArmin Le Grand } 661*4665f8d3SArmin Le Grand else 662*4665f8d3SArmin Le Grand { 663*4665f8d3SArmin Le Grand const Polygon aToolsPoly( 664*4665f8d3SArmin Le Grand rRect, 665*4665f8d3SArmin Le Grand pA->GetStartPoint(), 666*4665f8d3SArmin Le Grand pA->GetEndPoint(), 667*4665f8d3SArmin Le Grand POLY_CHORD); 668*4665f8d3SArmin Le Grand 669*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 670*4665f8d3SArmin Le Grand aClips.back(), 671*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon(aToolsPoly.getB2DPolygon()), 672*4665f8d3SArmin Le Grand aTarget, 673*4665f8d3SArmin Le Grand false); // stroke 674*4665f8d3SArmin Le Grand } 675*4665f8d3SArmin Le Grand break; 676*4665f8d3SArmin Le Grand } 677*4665f8d3SArmin Le Grand 678*4665f8d3SArmin Le Grand case META_POLYLINE_ACTION : 679*4665f8d3SArmin Le Grand { 680*4665f8d3SArmin Le Grand const MetaPolyLineAction* pA = static_cast< const MetaPolyLineAction* >(pAction); 681*4665f8d3SArmin Le Grand 682*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 683*4665f8d3SArmin Le Grand aClips.back(), 684*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon(pA->GetPolygon().getB2DPolygon()), 685*4665f8d3SArmin Le Grand aTarget, 686*4665f8d3SArmin Le Grand true); // stroke 687*4665f8d3SArmin Le Grand break; 688*4665f8d3SArmin Le Grand } 689*4665f8d3SArmin Le Grand 690*4665f8d3SArmin Le Grand case META_POLYGON_ACTION : 691*4665f8d3SArmin Le Grand { 692*4665f8d3SArmin Le Grand const MetaPolygonAction* pA = static_cast< const MetaPolygonAction* >(pAction); 693*4665f8d3SArmin Le Grand 694*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 695*4665f8d3SArmin Le Grand aClips.back(), 696*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon(pA->GetPolygon().getB2DPolygon()), 697*4665f8d3SArmin Le Grand aTarget, 698*4665f8d3SArmin Le Grand false); // stroke 699*4665f8d3SArmin Le Grand break; 700*4665f8d3SArmin Le Grand } 701*4665f8d3SArmin Le Grand 702*4665f8d3SArmin Le Grand case META_POLYPOLYGON_ACTION : 703*4665f8d3SArmin Le Grand { 704*4665f8d3SArmin Le Grand const MetaPolyPolygonAction* pA = static_cast< const MetaPolyPolygonAction* >(pAction); 705*4665f8d3SArmin Le Grand const PolyPolygon& rPoly = pA->GetPolyPolygon(); 706*4665f8d3SArmin Le Grand 707*4665f8d3SArmin Le Grand bDone = handleGeometricContent( 708*4665f8d3SArmin Le Grand aClips.back(), 709*4665f8d3SArmin Le Grand rPoly.getB2DPolyPolygon(), 710*4665f8d3SArmin Le Grand aTarget, 711*4665f8d3SArmin Le Grand false); // stroke 712*4665f8d3SArmin Le Grand break; 713*4665f8d3SArmin Le Grand } 714*4665f8d3SArmin Le Grand 715*4665f8d3SArmin Le Grand // 716*4665f8d3SArmin Le Grand // bitmap actions, create BitmapEx with alpha channel derived 717*4665f8d3SArmin Le Grand // from clipping 718*4665f8d3SArmin Le Grand // 719*4665f8d3SArmin Le Grand case META_BMPEX_ACTION : 720*4665f8d3SArmin Le Grand { 721*4665f8d3SArmin Le Grand const MetaBmpExAction* pA = static_cast< const MetaBmpExAction* >(pAction); 722*4665f8d3SArmin Le Grand const BitmapEx& rBitmapEx = pA->GetBitmapEx(); 723*4665f8d3SArmin Le Grand 724*4665f8d3SArmin Le Grand // the logical size depends on the PrefSize of the given bitmap in 725*4665f8d3SArmin Le Grand // combination with the current MapMode 726*4665f8d3SArmin Le Grand Size aLogicalSize(rBitmapEx.GetPrefSize()); 727*4665f8d3SArmin Le Grand 728*4665f8d3SArmin Le Grand if(MAP_PIXEL == rBitmapEx.GetPrefMapMode().GetMapUnit()) 729*4665f8d3SArmin Le Grand { 730*4665f8d3SArmin Le Grand aLogicalSize = Application::GetDefaultDevice()->PixelToLogic(aLogicalSize, aMapModes.back().GetMapUnit()); 731*4665f8d3SArmin Le Grand } 732*4665f8d3SArmin Le Grand else 733*4665f8d3SArmin Le Grand { 734*4665f8d3SArmin Le Grand aLogicalSize = OutputDevice::LogicToLogic(aLogicalSize, rBitmapEx.GetPrefMapMode(), aMapModes.back().GetMapUnit()); 735*4665f8d3SArmin Le Grand } 736*4665f8d3SArmin Le Grand 737*4665f8d3SArmin Le Grand bDone = handleBitmapContent( 738*4665f8d3SArmin Le Grand aClips.back(), 739*4665f8d3SArmin Le Grand pA->GetPoint(), 740*4665f8d3SArmin Le Grand aLogicalSize, 741*4665f8d3SArmin Le Grand rBitmapEx, 742*4665f8d3SArmin Le Grand aTarget); 743*4665f8d3SArmin Le Grand break; 744*4665f8d3SArmin Le Grand } 745*4665f8d3SArmin Le Grand 746*4665f8d3SArmin Le Grand case META_BMP_ACTION : 747*4665f8d3SArmin Le Grand { 748*4665f8d3SArmin Le Grand const MetaBmpAction* pA = static_cast< const MetaBmpAction* >(pAction); 749*4665f8d3SArmin Le Grand const Bitmap& rBitmap = pA->GetBitmap(); 750*4665f8d3SArmin Le Grand 751*4665f8d3SArmin Le Grand // the logical size depends on the PrefSize of the given bitmap in 752*4665f8d3SArmin Le Grand // combination with the current MapMode 753*4665f8d3SArmin Le Grand Size aLogicalSize(rBitmap.GetPrefSize()); 754*4665f8d3SArmin Le Grand 755*4665f8d3SArmin Le Grand if(MAP_PIXEL == rBitmap.GetPrefMapMode().GetMapUnit()) 756*4665f8d3SArmin Le Grand { 757*4665f8d3SArmin Le Grand aLogicalSize = Application::GetDefaultDevice()->PixelToLogic(aLogicalSize, aMapModes.back().GetMapUnit()); 758*4665f8d3SArmin Le Grand } 759*4665f8d3SArmin Le Grand else 760*4665f8d3SArmin Le Grand { 761*4665f8d3SArmin Le Grand aLogicalSize = OutputDevice::LogicToLogic(aLogicalSize, rBitmap.GetPrefMapMode(), aMapModes.back().GetMapUnit()); 762*4665f8d3SArmin Le Grand } 763*4665f8d3SArmin Le Grand 764*4665f8d3SArmin Le Grand bDone = handleBitmapContent( 765*4665f8d3SArmin Le Grand aClips.back(), 766*4665f8d3SArmin Le Grand pA->GetPoint(), 767*4665f8d3SArmin Le Grand aLogicalSize, 768*4665f8d3SArmin Le Grand BitmapEx(rBitmap), 769*4665f8d3SArmin Le Grand aTarget); 770*4665f8d3SArmin Le Grand break; 771*4665f8d3SArmin Le Grand } 772*4665f8d3SArmin Le Grand 773*4665f8d3SArmin Le Grand case META_BMPEXSCALE_ACTION : 774*4665f8d3SArmin Le Grand { 775*4665f8d3SArmin Le Grand const MetaBmpExScaleAction* pA = static_cast< const MetaBmpExScaleAction* >(pAction); 776*4665f8d3SArmin Le Grand 777*4665f8d3SArmin Le Grand bDone = handleBitmapContent( 778*4665f8d3SArmin Le Grand aClips.back(), 779*4665f8d3SArmin Le Grand pA->GetPoint(), 780*4665f8d3SArmin Le Grand pA->GetSize(), 781*4665f8d3SArmin Le Grand pA->GetBitmapEx(), 782*4665f8d3SArmin Le Grand aTarget); 783*4665f8d3SArmin Le Grand break; 784*4665f8d3SArmin Le Grand } 785*4665f8d3SArmin Le Grand 786*4665f8d3SArmin Le Grand case META_BMPSCALE_ACTION : 787*4665f8d3SArmin Le Grand { 788*4665f8d3SArmin Le Grand const MetaBmpScaleAction* pA = static_cast< const MetaBmpScaleAction* >(pAction); 789*4665f8d3SArmin Le Grand 790*4665f8d3SArmin Le Grand bDone = handleBitmapContent( 791*4665f8d3SArmin Le Grand aClips.back(), 792*4665f8d3SArmin Le Grand pA->GetPoint(), 793*4665f8d3SArmin Le Grand pA->GetSize(), 794*4665f8d3SArmin Le Grand BitmapEx(pA->GetBitmap()), 795*4665f8d3SArmin Le Grand aTarget); 796*4665f8d3SArmin Le Grand break; 797*4665f8d3SArmin Le Grand } 798*4665f8d3SArmin Le Grand 799*4665f8d3SArmin Le Grand case META_BMPEXSCALEPART_ACTION : 800*4665f8d3SArmin Le Grand { 801*4665f8d3SArmin Le Grand const MetaBmpExScalePartAction* pA = static_cast< const MetaBmpExScalePartAction* >(pAction); 802*4665f8d3SArmin Le Grand const BitmapEx& rBitmapEx = pA->GetBitmapEx(); 803*4665f8d3SArmin Le Grand 804*4665f8d3SArmin Le Grand if(rBitmapEx.IsEmpty()) 805*4665f8d3SArmin Le Grand { 806*4665f8d3SArmin Le Grand // empty content 807*4665f8d3SArmin Le Grand bDone = true; 808*4665f8d3SArmin Le Grand } 809*4665f8d3SArmin Le Grand else 810*4665f8d3SArmin Le Grand { 811*4665f8d3SArmin Le Grand BitmapEx aCroppedBitmapEx(rBitmapEx); 812*4665f8d3SArmin Le Grand const Rectangle aCropRectangle(pA->GetSrcPoint(), pA->GetSrcSize()); 813*4665f8d3SArmin Le Grand 814*4665f8d3SArmin Le Grand if(aCropRectangle.IsEmpty()) 815*4665f8d3SArmin Le Grand { 816*4665f8d3SArmin Le Grand // empty content 817*4665f8d3SArmin Le Grand bDone = true; 818*4665f8d3SArmin Le Grand } 819*4665f8d3SArmin Le Grand else 820*4665f8d3SArmin Le Grand { 821*4665f8d3SArmin Le Grand aCroppedBitmapEx.Crop(aCropRectangle); 822*4665f8d3SArmin Le Grand bDone = handleBitmapContent( 823*4665f8d3SArmin Le Grand aClips.back(), 824*4665f8d3SArmin Le Grand pA->GetDestPoint(), 825*4665f8d3SArmin Le Grand pA->GetDestSize(), 826*4665f8d3SArmin Le Grand aCroppedBitmapEx, 827*4665f8d3SArmin Le Grand aTarget); 828*4665f8d3SArmin Le Grand } 829*4665f8d3SArmin Le Grand } 830*4665f8d3SArmin Le Grand break; 831*4665f8d3SArmin Le Grand } 832*4665f8d3SArmin Le Grand 833*4665f8d3SArmin Le Grand case META_BMPSCALEPART_ACTION : 834*4665f8d3SArmin Le Grand { 835*4665f8d3SArmin Le Grand const MetaBmpScalePartAction* pA = static_cast< const MetaBmpScalePartAction* >(pAction); 836*4665f8d3SArmin Le Grand const Bitmap& rBitmap = pA->GetBitmap(); 837*4665f8d3SArmin Le Grand 838*4665f8d3SArmin Le Grand if(rBitmap.IsEmpty()) 839*4665f8d3SArmin Le Grand { 840*4665f8d3SArmin Le Grand // empty content 841*4665f8d3SArmin Le Grand bDone = true; 842*4665f8d3SArmin Le Grand } 843*4665f8d3SArmin Le Grand else 844*4665f8d3SArmin Le Grand { 845*4665f8d3SArmin Le Grand Bitmap aCroppedBitmap(rBitmap); 846*4665f8d3SArmin Le Grand const Rectangle aCropRectangle(pA->GetSrcPoint(), pA->GetSrcSize()); 847*4665f8d3SArmin Le Grand 848*4665f8d3SArmin Le Grand if(aCropRectangle.IsEmpty()) 849*4665f8d3SArmin Le Grand { 850*4665f8d3SArmin Le Grand // empty content 851*4665f8d3SArmin Le Grand bDone = true; 852*4665f8d3SArmin Le Grand } 853*4665f8d3SArmin Le Grand else 854*4665f8d3SArmin Le Grand { 855*4665f8d3SArmin Le Grand aCroppedBitmap.Crop(aCropRectangle); 856*4665f8d3SArmin Le Grand bDone = handleBitmapContent( 857*4665f8d3SArmin Le Grand aClips.back(), 858*4665f8d3SArmin Le Grand pA->GetDestPoint(), 859*4665f8d3SArmin Le Grand pA->GetDestSize(), 860*4665f8d3SArmin Le Grand BitmapEx(aCroppedBitmap), 861*4665f8d3SArmin Le Grand aTarget); 862*4665f8d3SArmin Le Grand } 863*4665f8d3SArmin Le Grand } 864*4665f8d3SArmin Le Grand break; 865*4665f8d3SArmin Le Grand } 866*4665f8d3SArmin Le Grand 867*4665f8d3SArmin Le Grand // 868*4665f8d3SArmin Le Grand // need to handle all those 'hacks' which hide data in comments 869*4665f8d3SArmin Le Grand // 870*4665f8d3SArmin Le Grand case META_COMMENT_ACTION : 871*4665f8d3SArmin Le Grand { 872*4665f8d3SArmin Le Grand const MetaCommentAction* pA = static_cast< const MetaCommentAction* >(pAction); 873*4665f8d3SArmin Le Grand const ByteString& rComment = pA->GetComment(); 874*4665f8d3SArmin Le Grand 875*4665f8d3SArmin Le Grand if(COMPARE_EQUAL == rComment.CompareIgnoreCaseToAscii("XGRAD_SEQ_BEGIN")) 876*4665f8d3SArmin Le Grand { 877*4665f8d3SArmin Le Grand // nothing to do; this just means that between here and XGRAD_SEQ_END 878*4665f8d3SArmin Le Grand // exists a META_GRADIENTEX_ACTION mixed with Xor-tricked painiting 879*4665f8d3SArmin Le Grand // commands. This comment is used to scan over these and filter for 880*4665f8d3SArmin Le Grand // the gradient action. It is needed to support META_GRADIENTEX_ACTION 881*4665f8d3SArmin Le Grand // in this processor to solve usages. 882*4665f8d3SArmin Le Grand } 883*4665f8d3SArmin Le Grand else if(COMPARE_EQUAL == rComment.CompareIgnoreCaseToAscii("XPATHFILL_SEQ_BEGIN")) 884*4665f8d3SArmin Le Grand { 885*4665f8d3SArmin Le Grand SvtGraphicFill aFilling; 886*4665f8d3SArmin Le Grand PolyPolygon aPath; 887*4665f8d3SArmin Le Grand 888*4665f8d3SArmin Le Grand { // read SvtGraphicFill 889*4665f8d3SArmin Le Grand SvMemoryStream aMemStm((void*)pA->GetData(), pA->GetDataSize(),STREAM_READ); 890*4665f8d3SArmin Le Grand aMemStm >> aFilling; 891*4665f8d3SArmin Le Grand } 892*4665f8d3SArmin Le Grand 893*4665f8d3SArmin Le Grand aFilling.getPath(aPath); 894*4665f8d3SArmin Le Grand 895*4665f8d3SArmin Le Grand if(aPath.Count()) 896*4665f8d3SArmin Le Grand { 897*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon aSource(aPath.getB2DPolyPolygon()); 898*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon aResult( 899*4665f8d3SArmin Le Grand basegfx::tools::clipPolyPolygonOnPolyPolygon( 900*4665f8d3SArmin Le Grand aSource, 901*4665f8d3SArmin Le Grand aClips.back(), 902*4665f8d3SArmin Le Grand true, // inside 903*4665f8d3SArmin Le Grand false)); // stroke 904*4665f8d3SArmin Le Grand 905*4665f8d3SArmin Le Grand if(aResult.count()) 906*4665f8d3SArmin Le Grand { 907*4665f8d3SArmin Le Grand if(aResult != aSource) 908*4665f8d3SArmin Le Grand { 909*4665f8d3SArmin Le Grand // add clipped geometry 910*4665f8d3SArmin Le Grand aFilling.setPath(PolyPolygon(aResult)); 911*4665f8d3SArmin Le Grand addSvtGraphicFill(aFilling, aTarget); 912*4665f8d3SArmin Le Grand bDone = true; 913*4665f8d3SArmin Le Grand } 914*4665f8d3SArmin Le Grand } 915*4665f8d3SArmin Le Grand else 916*4665f8d3SArmin Le Grand { 917*4665f8d3SArmin Le Grand // exchange with empty polygon 918*4665f8d3SArmin Le Grand aFilling.setPath(PolyPolygon()); 919*4665f8d3SArmin Le Grand addSvtGraphicFill(aFilling, aTarget); 920*4665f8d3SArmin Le Grand bDone = true; 921*4665f8d3SArmin Le Grand } 922*4665f8d3SArmin Le Grand } 923*4665f8d3SArmin Le Grand } 924*4665f8d3SArmin Le Grand else if(COMPARE_EQUAL == rComment.CompareIgnoreCaseToAscii("XPATHSTROKE_SEQ_BEGIN")) 925*4665f8d3SArmin Le Grand { 926*4665f8d3SArmin Le Grand SvtGraphicStroke aStroke; 927*4665f8d3SArmin Le Grand Polygon aPath; 928*4665f8d3SArmin Le Grand 929*4665f8d3SArmin Le Grand { // read SvtGraphicFill 930*4665f8d3SArmin Le Grand SvMemoryStream aMemStm((void*)pA->GetData(), pA->GetDataSize(),STREAM_READ); 931*4665f8d3SArmin Le Grand aMemStm >> aStroke; 932*4665f8d3SArmin Le Grand } 933*4665f8d3SArmin Le Grand 934*4665f8d3SArmin Le Grand aStroke.getPath(aPath); 935*4665f8d3SArmin Le Grand 936*4665f8d3SArmin Le Grand if(aPath.GetSize()) 937*4665f8d3SArmin Le Grand { 938*4665f8d3SArmin Le Grand const basegfx::B2DPolygon aSource(aPath.getB2DPolygon()); 939*4665f8d3SArmin Le Grand const basegfx::B2DPolyPolygon aResult( 940*4665f8d3SArmin Le Grand basegfx::tools::clipPolygonOnPolyPolygon( 941*4665f8d3SArmin Le Grand aSource, 942*4665f8d3SArmin Le Grand aClips.back(), 943*4665f8d3SArmin Le Grand true, // inside 944*4665f8d3SArmin Le Grand true)); // stroke 945*4665f8d3SArmin Le Grand 946*4665f8d3SArmin Le Grand if(aResult.count()) 947*4665f8d3SArmin Le Grand { 948*4665f8d3SArmin Le Grand if(aResult.count() > 1 || aResult.getB2DPolygon(0) != aSource) 949*4665f8d3SArmin Le Grand { 950*4665f8d3SArmin Le Grand // add clipped geometry 951*4665f8d3SArmin Le Grand for(sal_uInt32 a(0); a < aResult.count(); a++) 952*4665f8d3SArmin Le Grand { 953*4665f8d3SArmin Le Grand aStroke.setPath(Polygon(aResult.getB2DPolygon(a))); 954*4665f8d3SArmin Le Grand addSvtGraphicStroke(aStroke, aTarget); 955*4665f8d3SArmin Le Grand } 956*4665f8d3SArmin Le Grand 957*4665f8d3SArmin Le Grand bDone = true; 958*4665f8d3SArmin Le Grand } 959*4665f8d3SArmin Le Grand } 960*4665f8d3SArmin Le Grand else 961*4665f8d3SArmin Le Grand { 962*4665f8d3SArmin Le Grand // exchange with empty polygon 963*4665f8d3SArmin Le Grand aStroke.setPath(Polygon()); 964*4665f8d3SArmin Le Grand addSvtGraphicStroke(aStroke, aTarget); 965*4665f8d3SArmin Le Grand bDone = true; 966*4665f8d3SArmin Le Grand } 967*4665f8d3SArmin Le Grand 968*4665f8d3SArmin Le Grand } 969*4665f8d3SArmin Le Grand } 970*4665f8d3SArmin Le Grand break; 971*4665f8d3SArmin Le Grand } 972*4665f8d3SArmin Le Grand 973*4665f8d3SArmin Le Grand // 974*4665f8d3SArmin Le Grand // need to handle gradient fills (hopefully only unroated ones) 975*4665f8d3SArmin Le Grand // 976*4665f8d3SArmin Le Grand 977*4665f8d3SArmin Le Grand case META_GRADIENT_ACTION : 978*4665f8d3SArmin Le Grand { 979*4665f8d3SArmin Le Grand const MetaGradientAction* pA = static_cast< const MetaGradientAction* >(pAction); 980*4665f8d3SArmin Le Grand const Rectangle& rRect = pA->GetRect(); 981*4665f8d3SArmin Le Grand 982*4665f8d3SArmin Le Grand if(rRect.IsEmpty()) 983*4665f8d3SArmin Le Grand { 984*4665f8d3SArmin Le Grand bDone = true; 985*4665f8d3SArmin Le Grand } 986*4665f8d3SArmin Le Grand else 987*4665f8d3SArmin Le Grand { 988*4665f8d3SArmin Le Grand bDone = handleGradientContent( 989*4665f8d3SArmin Le Grand aClips.back(), 990*4665f8d3SArmin Le Grand basegfx::B2DPolyPolygon( 991*4665f8d3SArmin Le Grand basegfx::tools::createPolygonFromRect( 992*4665f8d3SArmin Le Grand basegfx::B2DRange( 993*4665f8d3SArmin Le Grand rRect.Left(), rRect.Top(), 994*4665f8d3SArmin Le Grand rRect.Right(), rRect.Bottom()))), 995*4665f8d3SArmin Le Grand pA->GetGradient(), 996*4665f8d3SArmin Le Grand aTarget); 997*4665f8d3SArmin Le Grand } 998*4665f8d3SArmin Le Grand 999*4665f8d3SArmin Le Grand 1000*4665f8d3SArmin Le Grand break; 1001*4665f8d3SArmin Le Grand } 1002*4665f8d3SArmin Le Grand 1003*4665f8d3SArmin Le Grand case META_GRADIENTEX_ACTION : 1004*4665f8d3SArmin Le Grand { 1005*4665f8d3SArmin Le Grand const MetaGradientExAction* pA = static_cast< const MetaGradientExAction* >(pAction); 1006*4665f8d3SArmin Le Grand const PolyPolygon& rPolyPoly = pA->GetPolyPolygon(); 1007*4665f8d3SArmin Le Grand 1008*4665f8d3SArmin Le Grand bDone = handleGradientContent( 1009*4665f8d3SArmin Le Grand aClips.back(), 1010*4665f8d3SArmin Le Grand rPolyPoly.getB2DPolyPolygon(), 1011*4665f8d3SArmin Le Grand pA->GetGradient(), 1012*4665f8d3SArmin Le Grand aTarget); 1013*4665f8d3SArmin Le Grand break; 1014*4665f8d3SArmin Le Grand } 1015*4665f8d3SArmin Le Grand 1016*4665f8d3SArmin Le Grand // not (yet) supported actions 1017*4665f8d3SArmin Le Grand // 1018*4665f8d3SArmin Le Grand // META_NULL_ACTION 1019*4665f8d3SArmin Le Grand // META_TEXT_ACTION 1020*4665f8d3SArmin Le Grand // META_TEXTARRAY_ACTION 1021*4665f8d3SArmin Le Grand // META_STRETCHTEXT_ACTION 1022*4665f8d3SArmin Le Grand // META_TEXTRECT_ACTION 1023*4665f8d3SArmin Le Grand // META_MASK_ACTION 1024*4665f8d3SArmin Le Grand // META_MASKSCALE_ACTION 1025*4665f8d3SArmin Le Grand // META_MASKSCALEPART_ACTION 1026*4665f8d3SArmin Le Grand // META_HATCH_ACTION 1027*4665f8d3SArmin Le Grand // META_WALLPAPER_ACTION 1028*4665f8d3SArmin Le Grand // META_FILLCOLOR_ACTION 1029*4665f8d3SArmin Le Grand // META_TEXTCOLOR_ACTION 1030*4665f8d3SArmin Le Grand // META_TEXTFILLCOLOR_ACTION 1031*4665f8d3SArmin Le Grand // META_TEXTALIGN_ACTION 1032*4665f8d3SArmin Le Grand // META_MAPMODE_ACTION 1033*4665f8d3SArmin Le Grand // META_FONT_ACTION 1034*4665f8d3SArmin Le Grand // META_TRANSPARENT_ACTION 1035*4665f8d3SArmin Le Grand // META_EPS_ACTION 1036*4665f8d3SArmin Le Grand // META_REFPOINT_ACTION 1037*4665f8d3SArmin Le Grand // META_TEXTLINECOLOR_ACTION 1038*4665f8d3SArmin Le Grand // META_TEXTLINE_ACTION 1039*4665f8d3SArmin Le Grand // META_FLOATTRANSPARENT_ACTION 1040*4665f8d3SArmin Le Grand // META_LAYOUTMODE_ACTION 1041*4665f8d3SArmin Le Grand // META_TEXTLANGUAGE_ACTION 1042*4665f8d3SArmin Le Grand // META_OVERLINECOLOR_ACTION 1043*4665f8d3SArmin Le Grand 1044*4665f8d3SArmin Le Grand // if an action is not handled at all, it will simply get copied to the 1045*4665f8d3SArmin Le Grand // target (see below). This is the default for all non-implemented actions 1046*4665f8d3SArmin Le Grand default: 1047*4665f8d3SArmin Le Grand { 1048*4665f8d3SArmin Le Grand break; 1049*4665f8d3SArmin Le Grand } 1050*4665f8d3SArmin Le Grand } 1051*4665f8d3SArmin Le Grand } 1052*4665f8d3SArmin Le Grand 1053*4665f8d3SArmin Le Grand if(bDone) 1054*4665f8d3SArmin Le Grand { 1055*4665f8d3SArmin Le Grand bChanged = true; 1056*4665f8d3SArmin Le Grand } 1057*4665f8d3SArmin Le Grand else 1058*4665f8d3SArmin Le Grand { 1059*4665f8d3SArmin Le Grand const_cast< MetaAction* >(pAction)->Duplicate(); 1060*4665f8d3SArmin Le Grand aTarget.AddAction(const_cast< MetaAction* >(pAction)); 1061*4665f8d3SArmin Le Grand } 1062*4665f8d3SArmin Le Grand } 1063*4665f8d3SArmin Le Grand 1064*4665f8d3SArmin Le Grand if(bChanged) 1065*4665f8d3SArmin Le Grand { 1066*4665f8d3SArmin Le Grand // when changed, copy back and do not forget to set MapMode 1067*4665f8d3SArmin Le Grand // and PrefSize 1068*4665f8d3SArmin Le Grand aTarget.SetPrefMapMode(rSource.GetPrefMapMode()); 1069*4665f8d3SArmin Le Grand aTarget.SetPrefSize(rSource.GetPrefSize()); 1070*4665f8d3SArmin Le Grand rSource = aTarget; 1071*4665f8d3SArmin Le Grand } 1072*4665f8d3SArmin Le Grand } 1073*4665f8d3SArmin Le Grand 1074*4665f8d3SArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 1075*4665f8d3SArmin Le Grand 1076*4665f8d3SArmin Le Grand bool VCL_DLLPUBLIC usesClipActions(const GDIMetaFile& rSource) 1077*4665f8d3SArmin Le Grand { 1078*4665f8d3SArmin Le Grand const sal_uLong nObjCount(rSource.GetActionCount()); 1079*4665f8d3SArmin Le Grand 1080*4665f8d3SArmin Le Grand for(sal_uLong i(0); i < nObjCount; ++i) 1081*4665f8d3SArmin Le Grand { 1082*4665f8d3SArmin Le Grand const MetaAction* pAction(rSource.GetAction(i)); 1083*4665f8d3SArmin Le Grand const sal_uInt16 nType(pAction->GetType()); 1084*4665f8d3SArmin Le Grand 1085*4665f8d3SArmin Le Grand switch(nType) 1086*4665f8d3SArmin Le Grand { 1087*4665f8d3SArmin Le Grand case META_CLIPREGION_ACTION : 1088*4665f8d3SArmin Le Grand case META_ISECTRECTCLIPREGION_ACTION : 1089*4665f8d3SArmin Le Grand case META_ISECTREGIONCLIPREGION_ACTION : 1090*4665f8d3SArmin Le Grand case META_MOVECLIPREGION_ACTION : 1091*4665f8d3SArmin Le Grand { 1092*4665f8d3SArmin Le Grand return true; 1093*4665f8d3SArmin Le Grand break; 1094*4665f8d3SArmin Le Grand } 1095*4665f8d3SArmin Le Grand 1096*4665f8d3SArmin Le Grand default: break; 1097*4665f8d3SArmin Le Grand } 1098*4665f8d3SArmin Le Grand } 1099*4665f8d3SArmin Le Grand 1100*4665f8d3SArmin Le Grand return false; 1101*4665f8d3SArmin Le Grand } 1102*4665f8d3SArmin Le Grand 1103*4665f8d3SArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 1104*4665f8d3SArmin Le Grand // eof 1105