1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <drawinglayer/processor2d/vclmetafileprocessor2d.hxx> 32*cdf0e10cSrcweir #include <tools/gen.hxx> 33*cdf0e10cSrcweir #include <vcl/virdev.hxx> 34*cdf0e10cSrcweir #include <vcl/gdimtf.hxx> 35*cdf0e10cSrcweir #include <vcl/gradient.hxx> 36*cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 37*cdf0e10cSrcweir #include <drawinglayer/primitive2d/textprimitive2d.hxx> 38*cdf0e10cSrcweir #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 39*cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 40*cdf0e10cSrcweir #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 41*cdf0e10cSrcweir #include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx> 42*cdf0e10cSrcweir #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> 43*cdf0e10cSrcweir #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 44*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygonclipper.hxx> 45*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx> 46*cdf0e10cSrcweir #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> 47*cdf0e10cSrcweir #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 48*cdf0e10cSrcweir #include <drawinglayer/primitive2d/transparenceprimitive2d.hxx> 49*cdf0e10cSrcweir #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx> 50*cdf0e10cSrcweir #include <drawinglayer/processor2d/vclpixelprocessor2d.hxx> 51*cdf0e10cSrcweir #include <tools/stream.hxx> 52*cdf0e10cSrcweir #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 53*cdf0e10cSrcweir #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> 54*cdf0e10cSrcweir #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx> 55*cdf0e10cSrcweir #include <vcl/graphictools.hxx> 56*cdf0e10cSrcweir #include <vcl/metaact.hxx> 57*cdf0e10cSrcweir #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> 58*cdf0e10cSrcweir #include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx> 59*cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 60*cdf0e10cSrcweir #include <rtl/ustring.hxx> 61*cdf0e10cSrcweir #include <com/sun/star/i18n/CharacterIteratorMode.hdl> 62*cdf0e10cSrcweir #include <com/sun/star/i18n/WordType.hpp> 63*cdf0e10cSrcweir #include <drawinglayer/primitive2d/controlprimitive2d.hxx> 64*cdf0e10cSrcweir #include <drawinglayer/primitive2d/graphicprimitive2d.hxx> 65*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 66*cdf0e10cSrcweir #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> 67*cdf0e10cSrcweir #include <helperchartrenderer.hxx> 68*cdf0e10cSrcweir #include <drawinglayer/primitive2d/epsprimitive2d.hxx> 69*cdf0e10cSrcweir #include <basegfx/polygon/b2dlinegeometry.hxx> 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 72*cdf0e10cSrcweir // for PDFExtOutDevData Graphic support 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir #include <vcl/graph.hxx> 75*cdf0e10cSrcweir #include <vcl/svapp.hxx> 76*cdf0e10cSrcweir #include <toolkit/helper/formpdfexport.hxx> 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 79*cdf0e10cSrcweir // for Control printing 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 84*cdf0e10cSrcweir // for current chart PrettyPrinting support 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir #include <drawinglayer/primitive2d/chartprimitive2d.hxx> 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 89*cdf0e10cSrcweir // for StructureTagPrimitive support in sd's unomodel.cxx 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir #include <drawinglayer/primitive2d/structuretagprimitive2d.hxx> 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir using namespace com::sun::star; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 98*cdf0e10cSrcweir // #112245# definition for maximum allowed point count due to Metafile target. 99*cdf0e10cSrcweir // To be on the safe side with the old tools polygon, use slightly less then 100*cdf0e10cSrcweir // the theoretical maximum (bad experiences with tools polygon) 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir #define MAX_POLYGON_POINT_COUNT_METAFILE (0x0000fff0) 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir namespace 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir // #112245# helper to split line polygon in half 109*cdf0e10cSrcweir void splitLinePolygon( 110*cdf0e10cSrcweir const basegfx::B2DPolygon& rBasePolygon, 111*cdf0e10cSrcweir basegfx::B2DPolygon& o_aLeft, 112*cdf0e10cSrcweir basegfx::B2DPolygon& o_aRight) 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir const sal_uInt32 nCount(rBasePolygon.count()); 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir if(nCount) 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir const sal_uInt32 nHalfCount((nCount - 1) >> 1); 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir o_aLeft = basegfx::B2DPolygon(rBasePolygon, 0, nHalfCount + 1); 121*cdf0e10cSrcweir o_aLeft.setClosed(false); 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir o_aRight = basegfx::B2DPolygon(rBasePolygon, nHalfCount, nCount - nHalfCount); 124*cdf0e10cSrcweir o_aRight.setClosed(false); 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir if(rBasePolygon.isClosed()) 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir o_aRight.append(rBasePolygon.getB2DPoint(0)); 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir if(rBasePolygon.areControlPointsUsed()) 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir o_aRight.setControlPoints( 133*cdf0e10cSrcweir o_aRight.count() - 1, 134*cdf0e10cSrcweir rBasePolygon.getPrevControlPoint(0), 135*cdf0e10cSrcweir rBasePolygon.getNextControlPoint(0)); 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir } 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir else 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir o_aLeft.clear(); 142*cdf0e10cSrcweir o_aRight.clear(); 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir // #112245# helper to evtl. split filled polygons to maximum metafile point count 147*cdf0e10cSrcweir bool fillPolyPolygonNeededToBeSplit(basegfx::B2DPolyPolygon& rPolyPolygon) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir bool bRetval(false); 150*cdf0e10cSrcweir const sal_uInt32 nPolyCount(rPolyPolygon.count()); 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir if(nPolyCount) 153*cdf0e10cSrcweir { 154*cdf0e10cSrcweir basegfx::B2DPolyPolygon aSplitted; 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir for(sal_uInt32 a(0); a < nPolyCount; a++) 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir const basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(a)); 159*cdf0e10cSrcweir const sal_uInt32 nPointCount(aCandidate.count()); 160*cdf0e10cSrcweir bool bNeedToSplit(false); 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir if(aCandidate.areControlPointsUsed()) 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir // compare with the maximum for bezier curved polygons 165*cdf0e10cSrcweir bNeedToSplit = nPointCount > ((MAX_POLYGON_POINT_COUNT_METAFILE / 3L) - 1L); 166*cdf0e10cSrcweir } 167*cdf0e10cSrcweir else 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir // compare with the maximum for simple point polygons 170*cdf0e10cSrcweir bNeedToSplit = nPointCount > (MAX_POLYGON_POINT_COUNT_METAFILE - 1); 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir if(bNeedToSplit) 174*cdf0e10cSrcweir { 175*cdf0e10cSrcweir // need to split the partial polygon 176*cdf0e10cSrcweir const basegfx::B2DRange aRange(aCandidate.getB2DRange()); 177*cdf0e10cSrcweir const basegfx::B2DPoint aCenter(aRange.getCenter()); 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir if(aRange.getWidth() > aRange.getHeight()) 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir // clip in left and right 182*cdf0e10cSrcweir const basegfx::B2DPolyPolygon aLeft( 183*cdf0e10cSrcweir basegfx::tools::clipPolygonOnParallelAxis( 184*cdf0e10cSrcweir aCandidate, 185*cdf0e10cSrcweir false, 186*cdf0e10cSrcweir true, 187*cdf0e10cSrcweir aCenter.getX(), 188*cdf0e10cSrcweir false)); 189*cdf0e10cSrcweir const basegfx::B2DPolyPolygon aRight( 190*cdf0e10cSrcweir basegfx::tools::clipPolygonOnParallelAxis( 191*cdf0e10cSrcweir aCandidate, 192*cdf0e10cSrcweir false, 193*cdf0e10cSrcweir false, 194*cdf0e10cSrcweir aCenter.getX(), 195*cdf0e10cSrcweir false)); 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir aSplitted.append(aLeft); 198*cdf0e10cSrcweir aSplitted.append(aRight); 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir else 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir // clip in top and bottom 203*cdf0e10cSrcweir const basegfx::B2DPolyPolygon aTop( 204*cdf0e10cSrcweir basegfx::tools::clipPolygonOnParallelAxis( 205*cdf0e10cSrcweir aCandidate, 206*cdf0e10cSrcweir true, 207*cdf0e10cSrcweir true, 208*cdf0e10cSrcweir aCenter.getY(), 209*cdf0e10cSrcweir false)); 210*cdf0e10cSrcweir const basegfx::B2DPolyPolygon aBottom( 211*cdf0e10cSrcweir basegfx::tools::clipPolygonOnParallelAxis( 212*cdf0e10cSrcweir aCandidate, 213*cdf0e10cSrcweir true, 214*cdf0e10cSrcweir false, 215*cdf0e10cSrcweir aCenter.getY(), 216*cdf0e10cSrcweir false)); 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir aSplitted.append(aTop); 219*cdf0e10cSrcweir aSplitted.append(aBottom); 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir else 223*cdf0e10cSrcweir { 224*cdf0e10cSrcweir aSplitted.append(aCandidate); 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir } 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir if(aSplitted.count() != nPolyCount) 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir rPolyPolygon = aSplitted; 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir return bRetval; 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir } // end of anonymous namespace 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir namespace drawinglayer 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir namespace processor2d 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir Rectangle VclMetafileProcessor2D::impDumpToMetaFile( 245*cdf0e10cSrcweir const primitive2d::Primitive2DSequence& rContent, 246*cdf0e10cSrcweir GDIMetaFile& o_rContentMetafile) 247*cdf0e10cSrcweir { 248*cdf0e10cSrcweir // Prepare VDev, MetaFile and connections 249*cdf0e10cSrcweir OutputDevice* pLastOutputDevice = mpOutputDevice; 250*cdf0e10cSrcweir GDIMetaFile* pLastMetafile = mpMetaFile; 251*cdf0e10cSrcweir basegfx::B2DRange aPrimitiveRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rContent, getViewInformation2D())); 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir // transform primitive range with current transformation (e.g shadow offset) 254*cdf0e10cSrcweir aPrimitiveRange.transform(maCurrentTransformation); 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir const Rectangle aPrimitiveRectangle( 257*cdf0e10cSrcweir basegfx::fround(aPrimitiveRange.getMinX()), basegfx::fround(aPrimitiveRange.getMinY()), 258*cdf0e10cSrcweir basegfx::fround(aPrimitiveRange.getMaxX()), basegfx::fround(aPrimitiveRange.getMaxY())); 259*cdf0e10cSrcweir VirtualDevice aContentVDev; 260*cdf0e10cSrcweir MapMode aNewMapMode(pLastOutputDevice->GetMapMode()); 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir mpOutputDevice = &aContentVDev; 263*cdf0e10cSrcweir mpMetaFile = &o_rContentMetafile; 264*cdf0e10cSrcweir aContentVDev.EnableOutput(false); 265*cdf0e10cSrcweir aContentVDev.SetMapMode(pLastOutputDevice->GetMapMode()); 266*cdf0e10cSrcweir o_rContentMetafile.Record(&aContentVDev); 267*cdf0e10cSrcweir aContentVDev.SetLineColor(pLastOutputDevice->GetLineColor()); 268*cdf0e10cSrcweir aContentVDev.SetFillColor(pLastOutputDevice->GetFillColor()); 269*cdf0e10cSrcweir aContentVDev.SetFont(pLastOutputDevice->GetFont()); 270*cdf0e10cSrcweir aContentVDev.SetDrawMode(pLastOutputDevice->GetDrawMode()); 271*cdf0e10cSrcweir aContentVDev.SetSettings(pLastOutputDevice->GetSettings()); 272*cdf0e10cSrcweir aContentVDev.SetRefPoint(pLastOutputDevice->GetRefPoint()); 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir // dump to MetaFile 275*cdf0e10cSrcweir process(rContent); 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir // cleanups 278*cdf0e10cSrcweir o_rContentMetafile.Stop(); 279*cdf0e10cSrcweir o_rContentMetafile.WindStart(); 280*cdf0e10cSrcweir aNewMapMode.SetOrigin(aPrimitiveRectangle.TopLeft()); 281*cdf0e10cSrcweir o_rContentMetafile.SetPrefMapMode(aNewMapMode); 282*cdf0e10cSrcweir o_rContentMetafile.SetPrefSize(aPrimitiveRectangle.GetSize()); 283*cdf0e10cSrcweir mpOutputDevice = pLastOutputDevice; 284*cdf0e10cSrcweir mpMetaFile = pLastMetafile; 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir return aPrimitiveRectangle; 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir void VclMetafileProcessor2D::impConvertFillGradientAttributeToVCLGradient( 290*cdf0e10cSrcweir Gradient& o_rVCLGradient, 291*cdf0e10cSrcweir const attribute::FillGradientAttribute& rFiGrAtt, 292*cdf0e10cSrcweir bool bIsTransparenceGradient) 293*cdf0e10cSrcweir { 294*cdf0e10cSrcweir if(bIsTransparenceGradient) 295*cdf0e10cSrcweir { 296*cdf0e10cSrcweir // it's about transparence channel intensities (black/white), do not use color modifier 297*cdf0e10cSrcweir o_rVCLGradient.SetStartColor(Color(rFiGrAtt.getStartColor())); 298*cdf0e10cSrcweir o_rVCLGradient.SetEndColor(Color(rFiGrAtt.getEndColor())); 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir else 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir // use color modifier to influence start/end color of gradient 303*cdf0e10cSrcweir o_rVCLGradient.SetStartColor(Color(maBColorModifierStack.getModifiedColor(rFiGrAtt.getStartColor()))); 304*cdf0e10cSrcweir o_rVCLGradient.SetEndColor(Color(maBColorModifierStack.getModifiedColor(rFiGrAtt.getEndColor()))); 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir o_rVCLGradient.SetAngle(static_cast< sal_uInt16 >(rFiGrAtt.getAngle() * (1.0 / F_PI1800))); 308*cdf0e10cSrcweir o_rVCLGradient.SetBorder(static_cast< sal_uInt16 >(rFiGrAtt.getBorder() * 100.0)); 309*cdf0e10cSrcweir o_rVCLGradient.SetOfsX(static_cast< sal_uInt16 >(rFiGrAtt.getOffsetX() * 100.0)); 310*cdf0e10cSrcweir o_rVCLGradient.SetOfsY(static_cast< sal_uInt16 >(rFiGrAtt.getOffsetY() * 100.0)); 311*cdf0e10cSrcweir o_rVCLGradient.SetSteps(rFiGrAtt.getSteps()); 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir // defaults for intensity; those were computed into the start/end colors already 314*cdf0e10cSrcweir o_rVCLGradient.SetStartIntensity(100); 315*cdf0e10cSrcweir o_rVCLGradient.SetEndIntensity(100); 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir switch(rFiGrAtt.getStyle()) 318*cdf0e10cSrcweir { 319*cdf0e10cSrcweir default : // attribute::GRADIENTSTYLE_LINEAR : 320*cdf0e10cSrcweir { 321*cdf0e10cSrcweir o_rVCLGradient.SetStyle(GRADIENT_LINEAR); 322*cdf0e10cSrcweir break; 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_AXIAL : 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir o_rVCLGradient.SetStyle(GRADIENT_AXIAL); 327*cdf0e10cSrcweir break; 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_RADIAL : 330*cdf0e10cSrcweir { 331*cdf0e10cSrcweir o_rVCLGradient.SetStyle(GRADIENT_RADIAL); 332*cdf0e10cSrcweir break; 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_ELLIPTICAL : 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir o_rVCLGradient.SetStyle(GRADIENT_ELLIPTICAL); 337*cdf0e10cSrcweir break; 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_SQUARE : 340*cdf0e10cSrcweir { 341*cdf0e10cSrcweir o_rVCLGradient.SetStyle(GRADIENT_SQUARE); 342*cdf0e10cSrcweir break; 343*cdf0e10cSrcweir } 344*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_RECT : 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir o_rVCLGradient.SetStyle(GRADIENT_RECT); 347*cdf0e10cSrcweir break; 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir } 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir void VclMetafileProcessor2D::impStartSvtGraphicFill(SvtGraphicFill* pSvtGraphicFill) 353*cdf0e10cSrcweir { 354*cdf0e10cSrcweir if(pSvtGraphicFill && !mnSvtGraphicFillCount) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir SvMemoryStream aMemStm; 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir aMemStm << *pSvtGraphicFill; 359*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction("XPATHFILL_SEQ_BEGIN", 0, static_cast< const sal_uInt8* >(aMemStm.GetData()), aMemStm.Seek(STREAM_SEEK_TO_END))); 360*cdf0e10cSrcweir mnSvtGraphicFillCount++; 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir void VclMetafileProcessor2D::impEndSvtGraphicFill(SvtGraphicFill* pSvtGraphicFill) 365*cdf0e10cSrcweir { 366*cdf0e10cSrcweir if(pSvtGraphicFill && mnSvtGraphicFillCount) 367*cdf0e10cSrcweir { 368*cdf0e10cSrcweir mnSvtGraphicFillCount--; 369*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction("XPATHFILL_SEQ_END")); 370*cdf0e10cSrcweir delete pSvtGraphicFill; 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir SvtGraphicStroke* VclMetafileProcessor2D::impTryToCreateSvtGraphicStroke( 375*cdf0e10cSrcweir const basegfx::B2DPolygon& rB2DPolygon, 376*cdf0e10cSrcweir const basegfx::BColor* pColor, 377*cdf0e10cSrcweir const attribute::LineAttribute* pLineAttribute, 378*cdf0e10cSrcweir const attribute::StrokeAttribute* pStrokeAttribute, 379*cdf0e10cSrcweir const attribute::LineStartEndAttribute* pStart, 380*cdf0e10cSrcweir const attribute::LineStartEndAttribute* pEnd) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir SvtGraphicStroke* pRetval = 0; 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir if(rB2DPolygon.count() && !mnSvtGraphicStrokeCount) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir basegfx::BColor aStrokeColor; 387*cdf0e10cSrcweir basegfx::B2DPolyPolygon aStartArrow; 388*cdf0e10cSrcweir basegfx::B2DPolyPolygon aEndArrow; 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir if(pColor) 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir aStrokeColor = *pColor; 393*cdf0e10cSrcweir } 394*cdf0e10cSrcweir else if(pLineAttribute) 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir aStrokeColor = maBColorModifierStack.getModifiedColor(pLineAttribute->getColor()); 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir // It IS needed to record the stroke color at all in the metafile, 400*cdf0e10cSrcweir // SvtGraphicStroke has NO entry for stroke color(!) 401*cdf0e10cSrcweir mpOutputDevice->SetLineColor(Color(aStrokeColor)); 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir if(!rB2DPolygon.isClosed()) 404*cdf0e10cSrcweir { 405*cdf0e10cSrcweir double fPolyLength(0.0); 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir if(pStart && pStart->isActive()) 408*cdf0e10cSrcweir { 409*cdf0e10cSrcweir fPolyLength = basegfx::tools::getLength(rB2DPolygon); 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir aStartArrow = basegfx::tools::createAreaGeometryForLineStartEnd( 412*cdf0e10cSrcweir rB2DPolygon, pStart->getB2DPolyPolygon(), true, pStart->getWidth(), 413*cdf0e10cSrcweir fPolyLength, pStart->isCentered() ? 0.5 : 0.0, 0); 414*cdf0e10cSrcweir } 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir if(pEnd && pEnd->isActive()) 417*cdf0e10cSrcweir { 418*cdf0e10cSrcweir if(basegfx::fTools::equalZero(fPolyLength)) 419*cdf0e10cSrcweir { 420*cdf0e10cSrcweir fPolyLength = basegfx::tools::getLength(rB2DPolygon); 421*cdf0e10cSrcweir } 422*cdf0e10cSrcweir 423*cdf0e10cSrcweir aEndArrow = basegfx::tools::createAreaGeometryForLineStartEnd( 424*cdf0e10cSrcweir rB2DPolygon, pEnd->getB2DPolyPolygon(), false, pEnd->getWidth(), 425*cdf0e10cSrcweir fPolyLength, pEnd->isCentered() ? 0.5 : 0.0, 0); 426*cdf0e10cSrcweir } 427*cdf0e10cSrcweir } 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir SvtGraphicStroke::JoinType eJoin(SvtGraphicStroke::joinNone); 430*cdf0e10cSrcweir double fLineWidth(0.0); 431*cdf0e10cSrcweir double fMiterLength(0.0); 432*cdf0e10cSrcweir SvtGraphicStroke::DashArray aDashArray; 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir if(pLineAttribute) 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir // pre-fill fLineWidth 437*cdf0e10cSrcweir fLineWidth = pLineAttribute->getWidth(); 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir // pre-fill fMiterLength 440*cdf0e10cSrcweir fMiterLength = fLineWidth; 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir // get Join 443*cdf0e10cSrcweir switch(pLineAttribute->getLineJoin()) 444*cdf0e10cSrcweir { 445*cdf0e10cSrcweir default : // basegfx::B2DLINEJOIN_NONE : 446*cdf0e10cSrcweir { 447*cdf0e10cSrcweir eJoin = SvtGraphicStroke::joinNone; 448*cdf0e10cSrcweir break; 449*cdf0e10cSrcweir } 450*cdf0e10cSrcweir case basegfx::B2DLINEJOIN_BEVEL : 451*cdf0e10cSrcweir { 452*cdf0e10cSrcweir eJoin = SvtGraphicStroke::joinBevel; 453*cdf0e10cSrcweir break; 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir case basegfx::B2DLINEJOIN_MIDDLE : 456*cdf0e10cSrcweir case basegfx::B2DLINEJOIN_MITER : 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir eJoin = SvtGraphicStroke::joinMiter; 459*cdf0e10cSrcweir // ATM 15 degrees is assumed 460*cdf0e10cSrcweir fMiterLength /= rtl::math::sin(M_PI * (15.0 / 360.0)); 461*cdf0e10cSrcweir break; 462*cdf0e10cSrcweir } 463*cdf0e10cSrcweir case basegfx::B2DLINEJOIN_ROUND : 464*cdf0e10cSrcweir { 465*cdf0e10cSrcweir eJoin = SvtGraphicStroke::joinRound; 466*cdf0e10cSrcweir break; 467*cdf0e10cSrcweir } 468*cdf0e10cSrcweir } 469*cdf0e10cSrcweir } 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir if(pStrokeAttribute) 472*cdf0e10cSrcweir { 473*cdf0e10cSrcweir // copy dash array 474*cdf0e10cSrcweir aDashArray = pStrokeAttribute->getDotDashArray(); 475*cdf0e10cSrcweir } 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir // #i101734# apply current object transformation to created geometry. 478*cdf0e10cSrcweir // This is a partial fix. When a object transformation is used which 479*cdf0e10cSrcweir // e.g. contains a scaleX != scaleY, an unproportional scaling would 480*cdf0e10cSrcweir // have to be applied to the evtl. existing fat line. The current 481*cdf0e10cSrcweir // concept of PDF export and SvtGraphicStroke usage does simply not 482*cdf0e10cSrcweir // allow handling such definitions. The only clean way would be to 483*cdf0e10cSrcweir // add the transformation to SvtGraphicStroke and to handle it there 484*cdf0e10cSrcweir basegfx::B2DPolygon aB2DPolygon(rB2DPolygon); 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir aB2DPolygon.transform(maCurrentTransformation); 487*cdf0e10cSrcweir aStartArrow.transform(maCurrentTransformation); 488*cdf0e10cSrcweir aEndArrow.transform(maCurrentTransformation); 489*cdf0e10cSrcweir 490*cdf0e10cSrcweir pRetval = new SvtGraphicStroke( 491*cdf0e10cSrcweir Polygon(aB2DPolygon), 492*cdf0e10cSrcweir PolyPolygon(aStartArrow), 493*cdf0e10cSrcweir PolyPolygon(aEndArrow), 494*cdf0e10cSrcweir mfCurrentUnifiedTransparence, 495*cdf0e10cSrcweir fLineWidth, 496*cdf0e10cSrcweir SvtGraphicStroke::capButt, 497*cdf0e10cSrcweir eJoin, 498*cdf0e10cSrcweir fMiterLength, 499*cdf0e10cSrcweir aDashArray); 500*cdf0e10cSrcweir } 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir return pRetval; 503*cdf0e10cSrcweir } 504*cdf0e10cSrcweir 505*cdf0e10cSrcweir void VclMetafileProcessor2D::impStartSvtGraphicStroke(SvtGraphicStroke* pSvtGraphicStroke) 506*cdf0e10cSrcweir { 507*cdf0e10cSrcweir if(pSvtGraphicStroke && !mnSvtGraphicStrokeCount) 508*cdf0e10cSrcweir { 509*cdf0e10cSrcweir SvMemoryStream aMemStm; 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir aMemStm << *pSvtGraphicStroke; 512*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction("XPATHSTROKE_SEQ_BEGIN", 0, static_cast< const sal_uInt8* >(aMemStm.GetData()), aMemStm.Seek(STREAM_SEEK_TO_END))); 513*cdf0e10cSrcweir mnSvtGraphicStrokeCount++; 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir void VclMetafileProcessor2D::impEndSvtGraphicStroke(SvtGraphicStroke* pSvtGraphicStroke) 518*cdf0e10cSrcweir { 519*cdf0e10cSrcweir if(pSvtGraphicStroke && mnSvtGraphicStrokeCount) 520*cdf0e10cSrcweir { 521*cdf0e10cSrcweir mnSvtGraphicStrokeCount--; 522*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction("XPATHSTROKE_SEQ_END")); 523*cdf0e10cSrcweir delete pSvtGraphicStroke; 524*cdf0e10cSrcweir } 525*cdf0e10cSrcweir } 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir // init static break iterator 528*cdf0e10cSrcweir uno::Reference< ::com::sun::star::i18n::XBreakIterator > VclMetafileProcessor2D::mxBreakIterator; 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir VclMetafileProcessor2D::VclMetafileProcessor2D(const geometry::ViewInformation2D& rViewInformation, OutputDevice& rOutDev) 531*cdf0e10cSrcweir : VclProcessor2D(rViewInformation, rOutDev), 532*cdf0e10cSrcweir mpMetaFile(rOutDev.GetConnectMetaFile()), 533*cdf0e10cSrcweir mnSvtGraphicFillCount(0), 534*cdf0e10cSrcweir mnSvtGraphicStrokeCount(0), 535*cdf0e10cSrcweir mfCurrentUnifiedTransparence(0.0), 536*cdf0e10cSrcweir mpPDFExtOutDevData(dynamic_cast< vcl::PDFExtOutDevData* >(rOutDev.GetExtOutDevData())) 537*cdf0e10cSrcweir { 538*cdf0e10cSrcweir OSL_ENSURE(rOutDev.GetConnectMetaFile(), "VclMetafileProcessor2D: Used on OutDev which has no MetaFile Target (!)"); 539*cdf0e10cSrcweir // draw to logic coordinates, do not initialize maCurrentTransformation to viewTransformation 540*cdf0e10cSrcweir // but only to ObjectTransformation. Do not change MapMode of destination. 541*cdf0e10cSrcweir maCurrentTransformation = rViewInformation.getObjectTransformation(); 542*cdf0e10cSrcweir } 543*cdf0e10cSrcweir 544*cdf0e10cSrcweir VclMetafileProcessor2D::~VclMetafileProcessor2D() 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir // MapMode was not changed, no restore necessary 547*cdf0e10cSrcweir } 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir /*********************************************************************************************** 550*cdf0e10cSrcweir 551*cdf0e10cSrcweir Support of MetaCommentActions in the VclMetafileProcessor2D 552*cdf0e10cSrcweir Found MetaCommentActions and how they are supported: 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir XGRAD_SEQ_BEGIN, XGRAD_SEQ_END: 555*cdf0e10cSrcweir 556*cdf0e10cSrcweir Used inside OutputDevice::DrawGradient to mark the start and end of a MetaGradientEx action. 557*cdf0e10cSrcweir It is used in various exporters/importers to have direct access to the gradient before it 558*cdf0e10cSrcweir is rendered by VCL (and thus fragmented to polygon color actions and others). On that base, e.g. 559*cdf0e10cSrcweir the Metafile to SdrObject import creates it's gradient objects. 560*cdf0e10cSrcweir Best (and safest) way to support it here is to use PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D, 561*cdf0e10cSrcweir map it back to the corresponding tools PolyPolygon and the Gradient and just call 562*cdf0e10cSrcweir OutputDevice::DrawGradient which creates the necessary compatible actions. 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir XPATHFILL_SEQ_BEGIN, XPATHFILL_SEQ_END: 565*cdf0e10cSrcweir 566*cdf0e10cSrcweir Two producers, one is vcl/source/gdi/gdimtf.cxx, line 1273. There, it is transformed 567*cdf0e10cSrcweir inside GDIMetaFile::Rotate, nothing to take care of here. 568*cdf0e10cSrcweir The second producer is in graphics/svx/source/svdraw/impgrfll.cxx, line 374. This is used 569*cdf0e10cSrcweir with each incarnation of Imp_GraphicFill when a metafile is recorded, fillstyle is not 570*cdf0e10cSrcweir XFILL_NONE and not completely transparent. It creates a SvtGraphicFill and streams it 571*cdf0e10cSrcweir to the comment action. A closing end token is created in the destructor. 572*cdf0e10cSrcweir Usages of Imp_GraphicFill are in Do_Paint_Object-methods of SdrCircObj, SdrPathObj and 573*cdf0e10cSrcweir SdrRectObj. 574*cdf0e10cSrcweir The token users pick various actions from SvtGraphicFill, so it may need to be added for all kind 575*cdf0e10cSrcweir of filled objects, even simple colored polygons. It is added as extra information; the 576*cdf0e10cSrcweir Metafile actions between the two tokens are interpreted as output generated from those 577*cdf0e10cSrcweir fills. Thus, users have the choice to use the SvtGraphicFill info or the created output 578*cdf0e10cSrcweir actions. 579*cdf0e10cSrcweir Even for XFillTransparenceItem it is used, thus it may need to be supported in 580*cdf0e10cSrcweir UnifiedTransparencePrimitive2D, too, when interpreted as normally filled PolyPolygon. 581*cdf0e10cSrcweir Implemented for: 582*cdf0e10cSrcweir PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D, 583*cdf0e10cSrcweir PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D, 584*cdf0e10cSrcweir PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D, 585*cdf0e10cSrcweir PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D, 586*cdf0e10cSrcweir and for PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D when detected unified transparence 587*cdf0e10cSrcweir 588*cdf0e10cSrcweir XPATHSTROKE_SEQ_BEGIN, XPATHSTROKE_SEQ_END: 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir Similar to pathfill, but using SvtGraphicStroke instead. It also has two producers where one 591*cdf0e10cSrcweir is also the GDIMetaFile::Rotate. Another user is MetaCommentAction::Move which modifies the 592*cdf0e10cSrcweir contained path accordingly. 593*cdf0e10cSrcweir The other one is SdrObject::Imp_DrawLineGeometry. It's done when MetaFile is set at OutDev and 594*cdf0e10cSrcweir only when geometry is a single polygon (!). I see no reason for that; in the PS exporter this 595*cdf0e10cSrcweir would hinder to make use of PolyPolygon strokes. I will need to add support at: 596*cdf0e10cSrcweir PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D 597*cdf0e10cSrcweir PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D 598*cdf0e10cSrcweir PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D 599*cdf0e10cSrcweir This can be done hierarchical, too. 600*cdf0e10cSrcweir Okay, base implementation done based on those three primitives. 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir FIELD_SEQ_BEGIN, FIELD_SEQ_END 603*cdf0e10cSrcweir 604*cdf0e10cSrcweir Used from slideshow for URLs, created from diverse SvxField implementations inside 605*cdf0e10cSrcweir createBeginComment()/createEndComment(). createBeginComment() is used from editeng\impedit3.cxx 606*cdf0e10cSrcweir inside ImpEditEngine::Paint. 607*cdf0e10cSrcweir Created TextHierarchyFieldPrimitive2D and added needed infos there; it is an group primitive and wraps 608*cdf0e10cSrcweir text primitives (but is not limited to that). It contains the field type if special actions for the 609*cdf0e10cSrcweir support of FIELD_SEQ_BEGIN/END are needed; this is the case for Page and URL fields. If more is 610*cdf0e10cSrcweir needed, it may be supported there. 611*cdf0e10cSrcweir FIELD_SEQ_BEGIN;PageField 612*cdf0e10cSrcweir FIELD_SEQ_END 613*cdf0e10cSrcweir Okay, these are now completely supported by TextHierarchyFieldPrimitive2D. URL works, too. 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir XTEXT 616*cdf0e10cSrcweir 617*cdf0e10cSrcweir XTEXT_EOC(i) end of character 618*cdf0e10cSrcweir XTEXT_EOW(i) end of word 619*cdf0e10cSrcweir XTEXT_EOS(i) end of sentence 620*cdf0e10cSrcweir 621*cdf0e10cSrcweir this three are with index and are created with the help of a i18n::XBreakIterator in 622*cdf0e10cSrcweir ImplDrawWithComments. Simplifying, moving out text painting, reworking to create some 623*cdf0e10cSrcweir data structure for holding those TEXT infos. 624*cdf0e10cSrcweir Supported directly by TextSimplePortionPrimitive2D with adding a Locale to the basic text 625*cdf0e10cSrcweir primitive. In the MetaFileRenderer, the creation is now done (see below). This has the advantage 626*cdf0e10cSrcweir that this creations do not need to be done for all paints all the time. This would be 627*cdf0e10cSrcweir expensive since the BreakIterator and it's usage is expensive and for each paint also the 628*cdf0e10cSrcweir whole character stops would need to be created. 629*cdf0e10cSrcweir Created only for TextDecoratedPortionPrimitive2D due to XTEXT_EOL and XTEXT_EOP (see below) 630*cdf0e10cSrcweir 631*cdf0e10cSrcweir XTEXT_EOL() end of line 632*cdf0e10cSrcweir XTEXT_EOP() end of paragraph 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir First try with boolean marks at TextDecoratedPortionPrimitive2D did not work too well, 635*cdf0e10cSrcweir i decided to solve it with structure. I added the TextHierarchyPrimitives for this, 636*cdf0e10cSrcweir namely: 637*cdf0e10cSrcweir - TextHierarchyLinePrimitive2D: Encapsulates single line 638*cdf0e10cSrcweir - TextHierarchyParagraphPrimitive2D: Encapsulates single paragraph 639*cdf0e10cSrcweir - TextHierarchyBlockPrimitive2D: encapsulates object texts (only one ATM) 640*cdf0e10cSrcweir Those are now supported in hierarchy. This means the MetaFile renderer will support them 641*cdf0e10cSrcweir by using them, reculrively using their content and adding MetaFile comments as needed. 642*cdf0e10cSrcweir This also means that when another text layouter will be used it will be necessary to 643*cdf0e10cSrcweir create/support the same HierarchyPrimitives to support users. 644*cdf0e10cSrcweir To transport the information using this hierarchy is best suited to all future needs; 645*cdf0e10cSrcweir the slideshow will be able to profit from it directly when using primitives; all other 646*cdf0e10cSrcweir renderers not interested in the text structure will just ignore the encapsulations. 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir XTEXT_PAINTSHAPE_BEGIN, XTEXT_PAINTSHAPE_END 649*cdf0e10cSrcweir Supported now by the TextHierarchyBlockPrimitive2D. 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir EPSReplacementGraphic: 652*cdf0e10cSrcweir Only used in goodies\source\filter.vcl\ieps\ieps.cxx and svx\source\xml\xmlgrhlp.cxx to 653*cdf0e10cSrcweir hold the original EPS which was imported in the same MetaFile as first 2 entries. Only 654*cdf0e10cSrcweir used to export the original again (if exists). 655*cdf0e10cSrcweir Not necessary to support with MetaFuleRenderer. 656*cdf0e10cSrcweir 657*cdf0e10cSrcweir XTEXT_SCROLLRECT, XTEXT_PAINTRECT 658*cdf0e10cSrcweir Currently used to get extra MetaFile infos using GraphicExporter which again uses 659*cdf0e10cSrcweir SdrTextObj::GetTextScrollMetaFileAndRectangle(). ATM works with primitives since 660*cdf0e10cSrcweir the rectangle data is added directly by the GraphicsExporter as comment. Does not need 661*cdf0e10cSrcweir to be adapted at once. 662*cdf0e10cSrcweir When adapting later, the only user - the diashow - should directly use the provided 663*cdf0e10cSrcweir Anination infos in the appropriate primitives (e.g. AnimatedSwitchPrimitive2D) 664*cdf0e10cSrcweir 665*cdf0e10cSrcweir PRNSPOOL_TRANSPARENTBITMAP_BEGIN, PRNSPOOL_TRANSPARENTBITMAP_END 666*cdf0e10cSrcweir VCL usage when printing PL -> THB. Okay, THB confirms that it is only used as 667*cdf0e10cSrcweir a fix (hack) while VCL printing. It is needed to not downscale a bitmap which 668*cdf0e10cSrcweir was explicitely created for the printer already again to some default maximum 669*cdf0e10cSrcweir bitmap sizes. 670*cdf0e10cSrcweir Nothing to do here for the primitive renderer. 671*cdf0e10cSrcweir 672*cdf0e10cSrcweir Support for vcl::PDFExtOutDevData: 673*cdf0e10cSrcweir PL knows that SJ did that stuff, it's used to hold a pointer to PDFExtOutDevData at 674*cdf0e10cSrcweir the OutDev. When set, some extra data is written there. Trying simple PDF export and 675*cdf0e10cSrcweir watching if i get those infos. 676*cdf0e10cSrcweir Well, a PDF export does not use e.g. ImpEditEngine::Paint since the PdfFilter uses 677*cdf0e10cSrcweir the SdXImpressDocument::render and thus uses the VclMetafileProcessor2D. I will check 678*cdf0e10cSrcweir if i get a PDFExtOutDevData at the target output device. 679*cdf0e10cSrcweir Indeed, i get one. Checking what all may be done when that extra-device-info is there. 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir All in all i have to talk to SJ. I will need to emulate some of those actions, but 682*cdf0e10cSrcweir i need to discuss which ones. 683*cdf0e10cSrcweir In the future, all those infos would be taken from the primitive sequence anyways, 684*cdf0e10cSrcweir thus these extensions would potentially be temporary, too. 685*cdf0e10cSrcweir Discussed with SJ, added the necessary support and tested it. Details follow. 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir - In ImpEditEngine::Paint, paragraph infos and URL stuff is added. 688*cdf0e10cSrcweir Added in primitive MetaFile renderer. 689*cdf0e10cSrcweir Checking URL: Indeed, current version exports it, but it is missing in primitive 690*cdf0e10cSrcweir CWS version. Adding support. 691*cdf0e10cSrcweir Okay, URLs work. Checked, Done. 692*cdf0e10cSrcweir 693*cdf0e10cSrcweir - UnoControlPDFExportContact is only created when PDFExtOutDevData is used at the 694*cdf0e10cSrcweir target and uno control data is created in UnoControlPDFExportContact::do_PaintObject. 695*cdf0e10cSrcweir This may be added in primitive MetaFile renderer. 696*cdf0e10cSrcweir Adding support... 697*cdf0e10cSrcweir OOps, the necessary helper stuff is in svx/source/form/formpdxexport.cxx in namespace 698*cdf0e10cSrcweir svxform. Have to talk to FS if this has to be like that. Especially since 699*cdf0e10cSrcweir ::vcl::PDFWriter::AnyWidget is filled out, which is already part of vcl. 700*cdf0e10cSrcweir Wrote an eMail to FS, he is on vacation currently. I see no reason why not to move 701*cdf0e10cSrcweir that stuff to somewhere else, maybe tools or svtools ?!? We will see... 702*cdf0e10cSrcweir Moved to toolkit, so i have to link against it. I tried VCL first, but it did 703*cdf0e10cSrcweir not work since VCLUnoHelper::CreateFont is unresolved in VCL (!). Other then the name 704*cdf0e10cSrcweir may imply, it is defined in toolkit (!). Since toolkit is linked against VCL itself, 705*cdf0e10cSrcweir the lowest move,ment plave is toolkit. 706*cdf0e10cSrcweir Checked form control export, it works well. Done. 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir - In goodies, in GraphicObject::Draw, when the used Graphic is linked, infos are 709*cdf0e10cSrcweir generated. I will need to check what happens here with primitives. 710*cdf0e10cSrcweir To support, use of GraphicPrimitive2D (PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D) may be needed. 711*cdf0e10cSrcweir Added support, but feature is broken in main version, so i cannot test at all. 712*cdf0e10cSrcweir Writing a bug to CL (or SJ) and seeing what happens (#i80380#). 713*cdf0e10cSrcweir SJ took a look and we got it working. Tested VCL MetaFile Renderer based export, 714*cdf0e10cSrcweir as intended, the original file is exported. Works, Done. 715*cdf0e10cSrcweir 716*cdf0e10cSrcweir 717*cdf0e10cSrcweir 718*cdf0e10cSrcweir 719*cdf0e10cSrcweir To be done: 720*cdf0e10cSrcweir 721*cdf0e10cSrcweir - Maybe there are more places to take care of for vcl::PDFExtOutDevData! 722*cdf0e10cSrcweir 723*cdf0e10cSrcweir 724*cdf0e10cSrcweir 725*cdf0e10cSrcweir ****************************************************************************************************/ 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir void VclMetafileProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) 728*cdf0e10cSrcweir { 729*cdf0e10cSrcweir switch(rCandidate.getPrimitive2DID()) 730*cdf0e10cSrcweir { 731*cdf0e10cSrcweir case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : 732*cdf0e10cSrcweir { 733*cdf0e10cSrcweir // directdraw of wrong spell primitive 734*cdf0e10cSrcweir // Ignore for VclMetafileProcessor2D, this is for printing and MetaFile recording only 735*cdf0e10cSrcweir break; 736*cdf0e10cSrcweir } 737*cdf0e10cSrcweir case PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D : 738*cdf0e10cSrcweir { 739*cdf0e10cSrcweir const primitive2d::GraphicPrimitive2D& rGraphicPrimitive = static_cast< const primitive2d::GraphicPrimitive2D& >(rCandidate); 740*cdf0e10cSrcweir bool bUsingPDFExtOutDevData(false); 741*cdf0e10cSrcweir basegfx::B2DVector aTranslate, aScale; 742*cdf0e10cSrcweir static bool bSuppressPDFExtOutDevDataSupport(false); 743*cdf0e10cSrcweir 744*cdf0e10cSrcweir if(mpPDFExtOutDevData && !bSuppressPDFExtOutDevDataSupport) 745*cdf0e10cSrcweir { 746*cdf0e10cSrcweir // emulate data handling from UnoControlPDFExportContact, original see 747*cdf0e10cSrcweir // svtools/source/graphic/grfmgr.cxx 748*cdf0e10cSrcweir const Graphic& rGraphic = rGraphicPrimitive.getGraphicObject().GetGraphic(); 749*cdf0e10cSrcweir 750*cdf0e10cSrcweir if(rGraphic.IsLink()) 751*cdf0e10cSrcweir { 752*cdf0e10cSrcweir const GraphicAttr& rAttr = rGraphicPrimitive.getGraphicAttr(); 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir if(!rAttr.IsSpecialDrawMode() && !rAttr.IsAdjusted()) 755*cdf0e10cSrcweir { 756*cdf0e10cSrcweir const basegfx::B2DHomMatrix& rTransform = rGraphicPrimitive.getTransform(); 757*cdf0e10cSrcweir double fRotate, fShearX; 758*cdf0e10cSrcweir rTransform.decompose(aScale, aTranslate, fRotate, fShearX); 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir if( basegfx::fTools::equalZero( fRotate ) && ( aScale.getX() > 0.0 ) && ( aScale.getY() > 0.0 ) ) 761*cdf0e10cSrcweir { 762*cdf0e10cSrcweir bUsingPDFExtOutDevData = true; 763*cdf0e10cSrcweir mpPDFExtOutDevData->BeginGroup(); 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir } 766*cdf0e10cSrcweir } 767*cdf0e10cSrcweir } 768*cdf0e10cSrcweir 769*cdf0e10cSrcweir // process recursively and add MetaFile comment 770*cdf0e10cSrcweir process(rGraphicPrimitive.get2DDecomposition(getViewInformation2D())); 771*cdf0e10cSrcweir 772*cdf0e10cSrcweir if(bUsingPDFExtOutDevData) 773*cdf0e10cSrcweir { 774*cdf0e10cSrcweir // emulate data handling from UnoControlPDFExportContact, original see 775*cdf0e10cSrcweir // svtools/source/graphic/grfmgr.cxx 776*cdf0e10cSrcweir const basegfx::B2DRange aCurrentRange( 777*cdf0e10cSrcweir aTranslate.getX(), aTranslate.getY(), 778*cdf0e10cSrcweir aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY()); 779*cdf0e10cSrcweir const Rectangle aCurrentRect( 780*cdf0e10cSrcweir sal_Int32(floor(aCurrentRange.getMinX())), sal_Int32(floor(aCurrentRange.getMinY())), 781*cdf0e10cSrcweir sal_Int32(ceil(aCurrentRange.getMaxX())), sal_Int32(ceil(aCurrentRange.getMaxY()))); 782*cdf0e10cSrcweir const GraphicAttr& rAttr = rGraphicPrimitive.getGraphicAttr(); 783*cdf0e10cSrcweir Rectangle aCropRect; 784*cdf0e10cSrcweir 785*cdf0e10cSrcweir if(rAttr.IsCropped()) 786*cdf0e10cSrcweir { 787*cdf0e10cSrcweir // calculate scalings between real image size and logic object size. This 788*cdf0e10cSrcweir // is necessary since the crop values are relative to original bitmap size 789*cdf0e10cSrcweir double fFactorX(1.0); 790*cdf0e10cSrcweir double fFactorY(1.0); 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir { 793*cdf0e10cSrcweir const MapMode aMapMode100thmm(MAP_100TH_MM); 794*cdf0e10cSrcweir const Size aBitmapSize(Application::GetDefaultDevice()->LogicToLogic( 795*cdf0e10cSrcweir rGraphicPrimitive.getGraphicObject().GetPrefSize(), 796*cdf0e10cSrcweir rGraphicPrimitive.getGraphicObject().GetPrefMapMode(), aMapMode100thmm)); 797*cdf0e10cSrcweir const double fDivX(aBitmapSize.Width() - rAttr.GetLeftCrop() - rAttr.GetRightCrop()); 798*cdf0e10cSrcweir const double fDivY(aBitmapSize.Height() - rAttr.GetTopCrop() - rAttr.GetBottomCrop()); 799*cdf0e10cSrcweir 800*cdf0e10cSrcweir if(!basegfx::fTools::equalZero(fDivX)) 801*cdf0e10cSrcweir { 802*cdf0e10cSrcweir fFactorX = aScale.getX() / fDivX; 803*cdf0e10cSrcweir } 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir if(!basegfx::fTools::equalZero(fDivY)) 806*cdf0e10cSrcweir { 807*cdf0e10cSrcweir fFactorY = aScale.getY() / fDivY; 808*cdf0e10cSrcweir } 809*cdf0e10cSrcweir } 810*cdf0e10cSrcweir 811*cdf0e10cSrcweir // calculate crop range and rect 812*cdf0e10cSrcweir basegfx::B2DRange aCropRange; 813*cdf0e10cSrcweir aCropRange.expand(aCurrentRange.getMinimum() - basegfx::B2DPoint(rAttr.GetLeftCrop() * fFactorX, rAttr.GetTopCrop() * fFactorY)); 814*cdf0e10cSrcweir aCropRange.expand(aCurrentRange.getMaximum() + basegfx::B2DPoint(rAttr.GetRightCrop() * fFactorX, rAttr.GetBottomCrop() * fFactorY)); 815*cdf0e10cSrcweir 816*cdf0e10cSrcweir aCropRect = Rectangle( 817*cdf0e10cSrcweir sal_Int32(floor(aCropRange.getMinX())), sal_Int32(floor(aCropRange.getMinY())), 818*cdf0e10cSrcweir sal_Int32(ceil(aCropRange.getMaxX())), sal_Int32(ceil(aCropRange.getMaxY()))); 819*cdf0e10cSrcweir } 820*cdf0e10cSrcweir 821*cdf0e10cSrcweir mpPDFExtOutDevData->EndGroup(rGraphicPrimitive.getGraphicObject().GetGraphic(), 822*cdf0e10cSrcweir rAttr.GetTransparency(), 823*cdf0e10cSrcweir aCurrentRect, 824*cdf0e10cSrcweir aCropRect); 825*cdf0e10cSrcweir } 826*cdf0e10cSrcweir 827*cdf0e10cSrcweir break; 828*cdf0e10cSrcweir } 829*cdf0e10cSrcweir case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D : 830*cdf0e10cSrcweir { 831*cdf0e10cSrcweir const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate); 832*cdf0e10cSrcweir const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl()); 833*cdf0e10cSrcweir bool bIsPrintableControl(false); 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir // find out if control is printable 836*cdf0e10cSrcweir if(rXControl.is()) 837*cdf0e10cSrcweir { 838*cdf0e10cSrcweir try 839*cdf0e10cSrcweir { 840*cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xModelProperties(rXControl->getModel(), uno::UNO_QUERY); 841*cdf0e10cSrcweir uno::Reference< beans::XPropertySetInfo > xPropertyInfo(xModelProperties.is() 842*cdf0e10cSrcweir ? xModelProperties->getPropertySetInfo() 843*cdf0e10cSrcweir : uno::Reference< beans::XPropertySetInfo >()); 844*cdf0e10cSrcweir const ::rtl::OUString sPrintablePropertyName(RTL_CONSTASCII_USTRINGPARAM("Printable")); 845*cdf0e10cSrcweir 846*cdf0e10cSrcweir if(xPropertyInfo.is() && xPropertyInfo->hasPropertyByName(sPrintablePropertyName)) 847*cdf0e10cSrcweir { 848*cdf0e10cSrcweir OSL_VERIFY(xModelProperties->getPropertyValue(sPrintablePropertyName) >>= bIsPrintableControl); 849*cdf0e10cSrcweir } 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir catch(const uno::Exception&) 852*cdf0e10cSrcweir { 853*cdf0e10cSrcweir OSL_ENSURE(false, "VclMetafileProcessor2D: No access to printable flag of Control, caught an exception!"); 854*cdf0e10cSrcweir } 855*cdf0e10cSrcweir } 856*cdf0e10cSrcweir 857*cdf0e10cSrcweir // PDF export and printing only for printable controls 858*cdf0e10cSrcweir if(bIsPrintableControl) 859*cdf0e10cSrcweir { 860*cdf0e10cSrcweir const bool bPDFExport(mpPDFExtOutDevData && mpPDFExtOutDevData->GetIsExportFormFields()); 861*cdf0e10cSrcweir bool bDoProcessRecursively(true); 862*cdf0e10cSrcweir 863*cdf0e10cSrcweir if(bPDFExport) 864*cdf0e10cSrcweir { 865*cdf0e10cSrcweir // PDF export. Emulate data handling from UnoControlPDFExportContact 866*cdf0e10cSrcweir // I have now moved describePDFControl to toolkit, thus i can implement the PDF 867*cdf0e10cSrcweir // form control support now as follows 868*cdf0e10cSrcweir ::std::auto_ptr< ::vcl::PDFWriter::AnyWidget > pPDFControl; 869*cdf0e10cSrcweir ::toolkitform::describePDFControl( rXControl, pPDFControl, *mpPDFExtOutDevData ); 870*cdf0e10cSrcweir 871*cdf0e10cSrcweir if(pPDFControl.get()) 872*cdf0e10cSrcweir { 873*cdf0e10cSrcweir // still need to fill in the location (is a class Rectangle) 874*cdf0e10cSrcweir const basegfx::B2DRange aRangeLogic(rControlPrimitive.getB2DRange(getViewInformation2D())); 875*cdf0e10cSrcweir const Rectangle aRectLogic( 876*cdf0e10cSrcweir (sal_Int32)floor(aRangeLogic.getMinX()), (sal_Int32)floor(aRangeLogic.getMinY()), 877*cdf0e10cSrcweir (sal_Int32)ceil(aRangeLogic.getMaxX()), (sal_Int32)ceil(aRangeLogic.getMaxY())); 878*cdf0e10cSrcweir pPDFControl->Location = aRectLogic; 879*cdf0e10cSrcweir 880*cdf0e10cSrcweir Size aFontSize(pPDFControl->TextFont.GetSize()); 881*cdf0e10cSrcweir aFontSize = mpOutputDevice->LogicToLogic(aFontSize, MapMode(MAP_POINT), mpOutputDevice->GetMapMode()); 882*cdf0e10cSrcweir pPDFControl->TextFont.SetSize(aFontSize); 883*cdf0e10cSrcweir 884*cdf0e10cSrcweir mpPDFExtOutDevData->BeginStructureElement(vcl::PDFWriter::Form); 885*cdf0e10cSrcweir mpPDFExtOutDevData->CreateControl(*pPDFControl.get()); 886*cdf0e10cSrcweir mpPDFExtOutDevData->EndStructureElement(); 887*cdf0e10cSrcweir 888*cdf0e10cSrcweir // no normal paint needed (see original UnoControlPDFExportContact::do_PaintObject); 889*cdf0e10cSrcweir // do not process recursively 890*cdf0e10cSrcweir bDoProcessRecursively = false; 891*cdf0e10cSrcweir } 892*cdf0e10cSrcweir else 893*cdf0e10cSrcweir { 894*cdf0e10cSrcweir // PDF export did not work, try simple output. 895*cdf0e10cSrcweir // Fallback to printer output by not setting bDoProcessRecursively 896*cdf0e10cSrcweir // to false. 897*cdf0e10cSrcweir } 898*cdf0e10cSrcweir } 899*cdf0e10cSrcweir 900*cdf0e10cSrcweir // #i93169# used flag the wrong way; true means that nothing was done yet 901*cdf0e10cSrcweir if(bDoProcessRecursively) 902*cdf0e10cSrcweir { 903*cdf0e10cSrcweir // printer output 904*cdf0e10cSrcweir try 905*cdf0e10cSrcweir { 906*cdf0e10cSrcweir // remember old graphics and create new 907*cdf0e10cSrcweir uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW); 908*cdf0e10cSrcweir const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics()); 909*cdf0e10cSrcweir const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics()); 910*cdf0e10cSrcweir 911*cdf0e10cSrcweir if(xNewGraphics.is()) 912*cdf0e10cSrcweir { 913*cdf0e10cSrcweir // link graphics and view 914*cdf0e10cSrcweir xControlView->setGraphics(xNewGraphics); 915*cdf0e10cSrcweir 916*cdf0e10cSrcweir // get position 917*cdf0e10cSrcweir const basegfx::B2DHomMatrix aObjectToDiscrete(getViewInformation2D().getObjectToViewTransformation() * rControlPrimitive.getTransform()); 918*cdf0e10cSrcweir const basegfx::B2DPoint aTopLeftDiscrete(aObjectToDiscrete * basegfx::B2DPoint(0.0, 0.0)); 919*cdf0e10cSrcweir 920*cdf0e10cSrcweir // draw it 921*cdf0e10cSrcweir xControlView->draw(basegfx::fround(aTopLeftDiscrete.getX()), basegfx::fround(aTopLeftDiscrete.getY())); 922*cdf0e10cSrcweir bDoProcessRecursively = false; 923*cdf0e10cSrcweir 924*cdf0e10cSrcweir // restore original graphics 925*cdf0e10cSrcweir xControlView->setGraphics(xOriginalGraphics); 926*cdf0e10cSrcweir } 927*cdf0e10cSrcweir } 928*cdf0e10cSrcweir catch( const uno::Exception& ) 929*cdf0e10cSrcweir { 930*cdf0e10cSrcweir OSL_ENSURE(false, "VclMetafileProcessor2D: Printing of Control failed, caught an exception!"); 931*cdf0e10cSrcweir } 932*cdf0e10cSrcweir } 933*cdf0e10cSrcweir 934*cdf0e10cSrcweir // process recursively if not done yet to export as decomposition (bitmap) 935*cdf0e10cSrcweir if(bDoProcessRecursively) 936*cdf0e10cSrcweir { 937*cdf0e10cSrcweir process(rControlPrimitive.get2DDecomposition(getViewInformation2D())); 938*cdf0e10cSrcweir } 939*cdf0e10cSrcweir } 940*cdf0e10cSrcweir 941*cdf0e10cSrcweir break; 942*cdf0e10cSrcweir } 943*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTHIERARCHYFIELDPRIMITIVE2D : 944*cdf0e10cSrcweir { 945*cdf0e10cSrcweir // support for FIELD_SEQ_BEGIN, FIELD_SEQ_END and URL. It wraps text primitives (but is not limited to) 946*cdf0e10cSrcweir // thus do the MetafileAction embedding stuff but just handle recursively. 947*cdf0e10cSrcweir const primitive2d::TextHierarchyFieldPrimitive2D& rFieldPrimitive = static_cast< const primitive2d::TextHierarchyFieldPrimitive2D& >(rCandidate); 948*cdf0e10cSrcweir static const ByteString aCommentStringCommon("FIELD_SEQ_BEGIN"); 949*cdf0e10cSrcweir static const ByteString aCommentStringPage("FIELD_SEQ_BEGIN;PageField"); 950*cdf0e10cSrcweir static const ByteString aCommentStringEnd("FIELD_SEQ_END"); 951*cdf0e10cSrcweir 952*cdf0e10cSrcweir switch(rFieldPrimitive.getType()) 953*cdf0e10cSrcweir { 954*cdf0e10cSrcweir default : // case drawinglayer::primitive2d::FIELD_TYPE_COMMON : 955*cdf0e10cSrcweir { 956*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentStringCommon)); 957*cdf0e10cSrcweir break; 958*cdf0e10cSrcweir } 959*cdf0e10cSrcweir case drawinglayer::primitive2d::FIELD_TYPE_PAGE : 960*cdf0e10cSrcweir { 961*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentStringPage)); 962*cdf0e10cSrcweir break; 963*cdf0e10cSrcweir } 964*cdf0e10cSrcweir case drawinglayer::primitive2d::FIELD_TYPE_URL : 965*cdf0e10cSrcweir { 966*cdf0e10cSrcweir const rtl::OUString& rURL = rFieldPrimitive.getString(); 967*cdf0e10cSrcweir const String aOldString(rURL); 968*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentStringCommon, 0, reinterpret_cast< const sal_uInt8* >(aOldString.GetBuffer()), 2 * aOldString.Len())); 969*cdf0e10cSrcweir break; 970*cdf0e10cSrcweir } 971*cdf0e10cSrcweir } 972*cdf0e10cSrcweir 973*cdf0e10cSrcweir // process recursively 974*cdf0e10cSrcweir const primitive2d::Primitive2DSequence rContent = rFieldPrimitive.get2DDecomposition(getViewInformation2D()); 975*cdf0e10cSrcweir process(rContent); 976*cdf0e10cSrcweir 977*cdf0e10cSrcweir // for the end comment the type is not relevant yet, they are all the same. Just add. 978*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentStringEnd)); 979*cdf0e10cSrcweir 980*cdf0e10cSrcweir if(mpPDFExtOutDevData && drawinglayer::primitive2d::FIELD_TYPE_URL == rFieldPrimitive.getType()) 981*cdf0e10cSrcweir { 982*cdf0e10cSrcweir // emulate data handling from ImpEditEngine::Paint 983*cdf0e10cSrcweir const basegfx::B2DRange aViewRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rContent, getViewInformation2D())); 984*cdf0e10cSrcweir const Rectangle aRectLogic( 985*cdf0e10cSrcweir (sal_Int32)floor(aViewRange.getMinX()), (sal_Int32)floor(aViewRange.getMinY()), 986*cdf0e10cSrcweir (sal_Int32)ceil(aViewRange.getMaxX()), (sal_Int32)ceil(aViewRange.getMaxY())); 987*cdf0e10cSrcweir vcl::PDFExtOutDevBookmarkEntry aBookmark; 988*cdf0e10cSrcweir aBookmark.nLinkId = mpPDFExtOutDevData->CreateLink(aRectLogic); 989*cdf0e10cSrcweir aBookmark.aBookmark = rFieldPrimitive.getString(); 990*cdf0e10cSrcweir std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = mpPDFExtOutDevData->GetBookmarks(); 991*cdf0e10cSrcweir rBookmarks.push_back( aBookmark ); 992*cdf0e10cSrcweir } 993*cdf0e10cSrcweir 994*cdf0e10cSrcweir break; 995*cdf0e10cSrcweir } 996*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTHIERARCHYLINEPRIMITIVE2D : 997*cdf0e10cSrcweir { 998*cdf0e10cSrcweir const primitive2d::TextHierarchyLinePrimitive2D& rLinePrimitive = static_cast< const primitive2d::TextHierarchyLinePrimitive2D& >(rCandidate); 999*cdf0e10cSrcweir static const ByteString aCommentString("XTEXT_EOL"); 1000*cdf0e10cSrcweir 1001*cdf0e10cSrcweir // process recursively and add MetaFile comment 1002*cdf0e10cSrcweir process(rLinePrimitive.get2DDecomposition(getViewInformation2D())); 1003*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentString)); 1004*cdf0e10cSrcweir 1005*cdf0e10cSrcweir break; 1006*cdf0e10cSrcweir } 1007*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTHIERARCHYBULLETPRIMITIVE2D : 1008*cdf0e10cSrcweir { 1009*cdf0e10cSrcweir // in Outliner::PaintBullet(), a MetafileComment for bullets is added, too. The 1010*cdf0e10cSrcweir // "XTEXT_EOC" is used, use here, too. 1011*cdf0e10cSrcweir const primitive2d::TextHierarchyBulletPrimitive2D& rBulletPrimitive = static_cast< const primitive2d::TextHierarchyBulletPrimitive2D& >(rCandidate); 1012*cdf0e10cSrcweir static const ByteString aCommentString("XTEXT_EOC"); 1013*cdf0e10cSrcweir 1014*cdf0e10cSrcweir // process recursively and add MetaFile comment 1015*cdf0e10cSrcweir process(rBulletPrimitive.get2DDecomposition(getViewInformation2D())); 1016*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentString)); 1017*cdf0e10cSrcweir 1018*cdf0e10cSrcweir break; 1019*cdf0e10cSrcweir } 1020*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTHIERARCHYPARAGRAPHPRIMITIVE2D : 1021*cdf0e10cSrcweir { 1022*cdf0e10cSrcweir const primitive2d::TextHierarchyParagraphPrimitive2D& rParagraphPrimitive = static_cast< const primitive2d::TextHierarchyParagraphPrimitive2D& >(rCandidate); 1023*cdf0e10cSrcweir static const ByteString aCommentString("XTEXT_EOP"); 1024*cdf0e10cSrcweir 1025*cdf0e10cSrcweir if(mpPDFExtOutDevData) 1026*cdf0e10cSrcweir { 1027*cdf0e10cSrcweir // emulate data handling from ImpEditEngine::Paint 1028*cdf0e10cSrcweir mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::Paragraph ); 1029*cdf0e10cSrcweir } 1030*cdf0e10cSrcweir 1031*cdf0e10cSrcweir // process recursively and add MetaFile comment 1032*cdf0e10cSrcweir process(rParagraphPrimitive.get2DDecomposition(getViewInformation2D())); 1033*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentString)); 1034*cdf0e10cSrcweir 1035*cdf0e10cSrcweir if(mpPDFExtOutDevData) 1036*cdf0e10cSrcweir { 1037*cdf0e10cSrcweir // emulate data handling from ImpEditEngine::Paint 1038*cdf0e10cSrcweir mpPDFExtOutDevData->EndStructureElement(); 1039*cdf0e10cSrcweir } 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir break; 1042*cdf0e10cSrcweir } 1043*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTHIERARCHYBLOCKPRIMITIVE2D : 1044*cdf0e10cSrcweir { 1045*cdf0e10cSrcweir const primitive2d::TextHierarchyBlockPrimitive2D& rBlockPrimitive = static_cast< const primitive2d::TextHierarchyBlockPrimitive2D& >(rCandidate); 1046*cdf0e10cSrcweir static const ByteString aCommentStringA("XTEXT_PAINTSHAPE_BEGIN"); 1047*cdf0e10cSrcweir static const ByteString aCommentStringB("XTEXT_PAINTSHAPE_END"); 1048*cdf0e10cSrcweir 1049*cdf0e10cSrcweir // add MetaFile comment, process recursively and add MetaFile comment 1050*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentStringA)); 1051*cdf0e10cSrcweir process(rBlockPrimitive.get2DDecomposition(getViewInformation2D())); 1052*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentStringB)); 1053*cdf0e10cSrcweir 1054*cdf0e10cSrcweir break; 1055*cdf0e10cSrcweir } 1056*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D : 1057*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D : 1058*cdf0e10cSrcweir { 1059*cdf0e10cSrcweir // for supporting TEXT_ MetaFile actions there is more to do here; get the candidate 1060*cdf0e10cSrcweir const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate = static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate); 1061*cdf0e10cSrcweir // const primitive2d::TextDecoratedPortionPrimitive2D* pTextDecoratedCandidate = dynamic_cast< const primitive2d::TextDecoratedPortionPrimitive2D* >(&rCandidate); 1062*cdf0e10cSrcweir 1063*cdf0e10cSrcweir // Adapt evtl. used special DrawMode 1064*cdf0e10cSrcweir const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 1065*cdf0e10cSrcweir adaptTextToFillDrawMode(); 1066*cdf0e10cSrcweir 1067*cdf0e10cSrcweir // directdraw of text simple portion; use default processing 1068*cdf0e10cSrcweir RenderTextSimpleOrDecoratedPortionPrimitive2D(rTextCandidate); 1069*cdf0e10cSrcweir 1070*cdf0e10cSrcweir // restore DrawMode 1071*cdf0e10cSrcweir mpOutputDevice->SetDrawMode(nOriginalDrawMode); 1072*cdf0e10cSrcweir 1073*cdf0e10cSrcweir // #i101169# if(pTextDecoratedCandidate) 1074*cdf0e10cSrcweir { 1075*cdf0e10cSrcweir // support for TEXT_ MetaFile actions only for decorated texts 1076*cdf0e10cSrcweir if(!mxBreakIterator.is()) 1077*cdf0e10cSrcweir { 1078*cdf0e10cSrcweir uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF(::comphelper::getProcessServiceFactory()); 1079*cdf0e10cSrcweir mxBreakIterator.set(xMSF->createInstance(rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator")), uno::UNO_QUERY); 1080*cdf0e10cSrcweir } 1081*cdf0e10cSrcweir 1082*cdf0e10cSrcweir if(mxBreakIterator.is()) 1083*cdf0e10cSrcweir { 1084*cdf0e10cSrcweir const rtl::OUString& rTxt = rTextCandidate.getText(); 1085*cdf0e10cSrcweir const sal_Int32 nTextLength(rTextCandidate.getTextLength()); // rTxt.getLength()); 1086*cdf0e10cSrcweir 1087*cdf0e10cSrcweir if(nTextLength) 1088*cdf0e10cSrcweir { 1089*cdf0e10cSrcweir const ::com::sun::star::lang::Locale& rLocale = rTextCandidate.getLocale(); 1090*cdf0e10cSrcweir const sal_Int32 nTextPosition(rTextCandidate.getTextPosition()); 1091*cdf0e10cSrcweir 1092*cdf0e10cSrcweir sal_Int32 nDone; 1093*cdf0e10cSrcweir sal_Int32 nNextCellBreak(mxBreakIterator->nextCharacters(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 0, nDone)); 1094*cdf0e10cSrcweir ::com::sun::star::i18n::Boundary nNextWordBoundary(mxBreakIterator->getWordBoundary(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True)); 1095*cdf0e10cSrcweir sal_Int32 nNextSentenceBreak(mxBreakIterator->endOfSentence(rTxt, nTextPosition, rLocale)); 1096*cdf0e10cSrcweir static const ByteString aCommentStringA("XTEXT_EOC"); 1097*cdf0e10cSrcweir static const ByteString aCommentStringB("XTEXT_EOW"); 1098*cdf0e10cSrcweir static const ByteString aCommentStringC("XTEXT_EOS"); 1099*cdf0e10cSrcweir 1100*cdf0e10cSrcweir for(sal_Int32 i(nTextPosition); i < nTextPosition + nTextLength; i++) 1101*cdf0e10cSrcweir { 1102*cdf0e10cSrcweir // create the entries for the respective break positions 1103*cdf0e10cSrcweir if(i == nNextCellBreak) 1104*cdf0e10cSrcweir { 1105*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentStringA, i - nTextPosition)); 1106*cdf0e10cSrcweir nNextCellBreak = mxBreakIterator->nextCharacters(rTxt, i, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone); 1107*cdf0e10cSrcweir } 1108*cdf0e10cSrcweir if(i == nNextWordBoundary.endPos) 1109*cdf0e10cSrcweir { 1110*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentStringB, i - nTextPosition)); 1111*cdf0e10cSrcweir nNextWordBoundary = mxBreakIterator->getWordBoundary(rTxt, i + 1, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True); 1112*cdf0e10cSrcweir } 1113*cdf0e10cSrcweir if(i == nNextSentenceBreak) 1114*cdf0e10cSrcweir { 1115*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaCommentAction(aCommentStringC, i - nTextPosition)); 1116*cdf0e10cSrcweir nNextSentenceBreak = mxBreakIterator->endOfSentence(rTxt, i + 1, rLocale); 1117*cdf0e10cSrcweir } 1118*cdf0e10cSrcweir } 1119*cdf0e10cSrcweir } 1120*cdf0e10cSrcweir } 1121*cdf0e10cSrcweir } 1122*cdf0e10cSrcweir 1123*cdf0e10cSrcweir break; 1124*cdf0e10cSrcweir } 1125*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : 1126*cdf0e10cSrcweir { 1127*cdf0e10cSrcweir const primitive2d::PolygonHairlinePrimitive2D& rHairlinePrimitive = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate); 1128*cdf0e10cSrcweir const basegfx::B2DPolygon& rBasePolygon = rHairlinePrimitive.getB2DPolygon(); 1129*cdf0e10cSrcweir 1130*cdf0e10cSrcweir if(rBasePolygon.count() > (MAX_POLYGON_POINT_COUNT_METAFILE - 1)) 1131*cdf0e10cSrcweir { 1132*cdf0e10cSrcweir // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points 1133*cdf0e10cSrcweir // per polygon. If there are more, split the polygon in half and call recursively 1134*cdf0e10cSrcweir basegfx::B2DPolygon aLeft, aRight; 1135*cdf0e10cSrcweir splitLinePolygon(rBasePolygon, aLeft, aRight); 1136*cdf0e10cSrcweir const primitive2d::PolygonHairlinePrimitive2D aPLeft(aLeft, rHairlinePrimitive.getBColor()); 1137*cdf0e10cSrcweir const primitive2d::PolygonHairlinePrimitive2D aPRight(aRight, rHairlinePrimitive.getBColor()); 1138*cdf0e10cSrcweir 1139*cdf0e10cSrcweir processBasePrimitive2D(aPLeft); 1140*cdf0e10cSrcweir processBasePrimitive2D(aPRight); 1141*cdf0e10cSrcweir } 1142*cdf0e10cSrcweir else 1143*cdf0e10cSrcweir { 1144*cdf0e10cSrcweir // direct draw of hairline; use default processing 1145*cdf0e10cSrcweir // support SvtGraphicStroke MetaCommentAction 1146*cdf0e10cSrcweir const basegfx::BColor aLineColor(maBColorModifierStack.getModifiedColor(rHairlinePrimitive.getBColor())); 1147*cdf0e10cSrcweir SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke( 1148*cdf0e10cSrcweir rHairlinePrimitive.getB2DPolygon(), 1149*cdf0e10cSrcweir &aLineColor, 1150*cdf0e10cSrcweir 0, 0, 0, 0); 1151*cdf0e10cSrcweir 1152*cdf0e10cSrcweir impStartSvtGraphicStroke(pSvtGraphicStroke); 1153*cdf0e10cSrcweir RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), false); 1154*cdf0e10cSrcweir impEndSvtGraphicStroke(pSvtGraphicStroke); 1155*cdf0e10cSrcweir } 1156*cdf0e10cSrcweir break; 1157*cdf0e10cSrcweir } 1158*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D : 1159*cdf0e10cSrcweir { 1160*cdf0e10cSrcweir const primitive2d::PolygonStrokePrimitive2D& rStrokePrimitive = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate); 1161*cdf0e10cSrcweir const basegfx::B2DPolygon& rBasePolygon = rStrokePrimitive.getB2DPolygon(); 1162*cdf0e10cSrcweir 1163*cdf0e10cSrcweir if(rBasePolygon.count() > (MAX_POLYGON_POINT_COUNT_METAFILE - 1)) 1164*cdf0e10cSrcweir { 1165*cdf0e10cSrcweir // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points 1166*cdf0e10cSrcweir // per polygon. If there are more, split the polygon in half and call recursively 1167*cdf0e10cSrcweir basegfx::B2DPolygon aLeft, aRight; 1168*cdf0e10cSrcweir splitLinePolygon(rBasePolygon, aLeft, aRight); 1169*cdf0e10cSrcweir const primitive2d::PolygonStrokePrimitive2D aPLeft( 1170*cdf0e10cSrcweir aLeft, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute()); 1171*cdf0e10cSrcweir const primitive2d::PolygonStrokePrimitive2D aPRight( 1172*cdf0e10cSrcweir aRight, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute()); 1173*cdf0e10cSrcweir 1174*cdf0e10cSrcweir processBasePrimitive2D(aPLeft); 1175*cdf0e10cSrcweir processBasePrimitive2D(aPRight); 1176*cdf0e10cSrcweir } 1177*cdf0e10cSrcweir else 1178*cdf0e10cSrcweir { 1179*cdf0e10cSrcweir // support SvtGraphicStroke MetaCommentAction 1180*cdf0e10cSrcweir SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke( 1181*cdf0e10cSrcweir rBasePolygon, 0, 1182*cdf0e10cSrcweir &rStrokePrimitive.getLineAttribute(), 1183*cdf0e10cSrcweir &rStrokePrimitive.getStrokeAttribute(), 1184*cdf0e10cSrcweir 0, 0); 1185*cdf0e10cSrcweir 1186*cdf0e10cSrcweir impStartSvtGraphicStroke(pSvtGraphicStroke); 1187*cdf0e10cSrcweir const attribute::LineAttribute& rLine = rStrokePrimitive.getLineAttribute(); 1188*cdf0e10cSrcweir 1189*cdf0e10cSrcweir // create MetaPolyLineActions, but without LINE_DASH 1190*cdf0e10cSrcweir if(basegfx::fTools::more(rLine.getWidth(), 0.0)) 1191*cdf0e10cSrcweir { 1192*cdf0e10cSrcweir const attribute::StrokeAttribute& rStroke = rStrokePrimitive.getStrokeAttribute(); 1193*cdf0e10cSrcweir basegfx::B2DPolyPolygon aHairLinePolyPolygon; 1194*cdf0e10cSrcweir 1195*cdf0e10cSrcweir if(0.0 == rStroke.getFullDotDashLen()) 1196*cdf0e10cSrcweir { 1197*cdf0e10cSrcweir aHairLinePolyPolygon.append(rBasePolygon); 1198*cdf0e10cSrcweir } 1199*cdf0e10cSrcweir else 1200*cdf0e10cSrcweir { 1201*cdf0e10cSrcweir basegfx::tools::applyLineDashing( 1202*cdf0e10cSrcweir rBasePolygon, rStroke.getDotDashArray(), 1203*cdf0e10cSrcweir &aHairLinePolyPolygon, 0, rStroke.getFullDotDashLen()); 1204*cdf0e10cSrcweir } 1205*cdf0e10cSrcweir 1206*cdf0e10cSrcweir const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLine.getColor())); 1207*cdf0e10cSrcweir mpOutputDevice->SetLineColor(Color(aHairlineColor)); 1208*cdf0e10cSrcweir mpOutputDevice->SetFillColor(); 1209*cdf0e10cSrcweir aHairLinePolyPolygon.transform(maCurrentTransformation); 1210*cdf0e10cSrcweir 1211*cdf0e10cSrcweir // #i113922# LineWidth needs to be transformed, too 1212*cdf0e10cSrcweir const basegfx::B2DVector aDiscreteUnit(maCurrentTransformation * basegfx::B2DVector(rLine.getWidth(), 0.0)); 1213*cdf0e10cSrcweir const double fDiscreteLineWidth(aDiscreteUnit.getLength()); 1214*cdf0e10cSrcweir 1215*cdf0e10cSrcweir LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fDiscreteLineWidth)); 1216*cdf0e10cSrcweir aLineInfo.SetLineJoin(rLine.getLineJoin()); 1217*cdf0e10cSrcweir 1218*cdf0e10cSrcweir for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++) 1219*cdf0e10cSrcweir { 1220*cdf0e10cSrcweir const basegfx::B2DPolygon aCandidate(aHairLinePolyPolygon.getB2DPolygon(a)); 1221*cdf0e10cSrcweir 1222*cdf0e10cSrcweir if(aCandidate.count() > 1) 1223*cdf0e10cSrcweir { 1224*cdf0e10cSrcweir const Polygon aToolsPolygon(aCandidate); 1225*cdf0e10cSrcweir 1226*cdf0e10cSrcweir mpMetaFile->AddAction(new MetaPolyLineAction(aToolsPolygon, aLineInfo)); 1227*cdf0e10cSrcweir } 1228*cdf0e10cSrcweir } 1229*cdf0e10cSrcweir } 1230*cdf0e10cSrcweir else 1231*cdf0e10cSrcweir { 1232*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 1233*cdf0e10cSrcweir } 1234*cdf0e10cSrcweir 1235*cdf0e10cSrcweir impEndSvtGraphicStroke(pSvtGraphicStroke); 1236*cdf0e10cSrcweir } 1237*cdf0e10cSrcweir 1238*cdf0e10cSrcweir break; 1239*cdf0e10cSrcweir } 1240*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D : 1241*cdf0e10cSrcweir { 1242*cdf0e10cSrcweir const primitive2d::PolygonStrokeArrowPrimitive2D& rStrokeArrowPrimitive = static_cast< const primitive2d::PolygonStrokeArrowPrimitive2D& >(rCandidate); 1243*cdf0e10cSrcweir const basegfx::B2DPolygon& rBasePolygon = rStrokeArrowPrimitive.getB2DPolygon(); 1244*cdf0e10cSrcweir 1245*cdf0e10cSrcweir if(rBasePolygon.count() > (MAX_POLYGON_POINT_COUNT_METAFILE - 1)) 1246*cdf0e10cSrcweir { 1247*cdf0e10cSrcweir // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points 1248*cdf0e10cSrcweir // per polygon. If there are more, split the polygon in half and call recursively 1249*cdf0e10cSrcweir basegfx::B2DPolygon aLeft, aRight; 1250*cdf0e10cSrcweir splitLinePolygon(rBasePolygon, aLeft, aRight); 1251*cdf0e10cSrcweir const attribute::LineStartEndAttribute aEmpty; 1252*cdf0e10cSrcweir const primitive2d::PolygonStrokeArrowPrimitive2D aPLeft( 1253*cdf0e10cSrcweir aLeft, 1254*cdf0e10cSrcweir rStrokeArrowPrimitive.getLineAttribute(), 1255*cdf0e10cSrcweir rStrokeArrowPrimitive.getStrokeAttribute(), 1256*cdf0e10cSrcweir rStrokeArrowPrimitive.getStart(), 1257*cdf0e10cSrcweir aEmpty); 1258*cdf0e10cSrcweir const primitive2d::PolygonStrokeArrowPrimitive2D aPRight( 1259*cdf0e10cSrcweir aRight, 1260*cdf0e10cSrcweir rStrokeArrowPrimitive.getLineAttribute(), 1261*cdf0e10cSrcweir rStrokeArrowPrimitive.getStrokeAttribute(), 1262*cdf0e10cSrcweir aEmpty, 1263*cdf0e10cSrcweir rStrokeArrowPrimitive.getEnd()); 1264*cdf0e10cSrcweir 1265*cdf0e10cSrcweir processBasePrimitive2D(aPLeft); 1266*cdf0e10cSrcweir processBasePrimitive2D(aPRight); 1267*cdf0e10cSrcweir } 1268*cdf0e10cSrcweir else 1269*cdf0e10cSrcweir { 1270*cdf0e10cSrcweir // support SvtGraphicStroke MetaCommentAction 1271*cdf0e10cSrcweir SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke( 1272*cdf0e10cSrcweir rBasePolygon, 0, 1273*cdf0e10cSrcweir &rStrokeArrowPrimitive.getLineAttribute(), 1274*cdf0e10cSrcweir &rStrokeArrowPrimitive.getStrokeAttribute(), 1275*cdf0e10cSrcweir &rStrokeArrowPrimitive.getStart(), 1276*cdf0e10cSrcweir &rStrokeArrowPrimitive.getEnd()); 1277*cdf0e10cSrcweir 1278*cdf0e10cSrcweir impStartSvtGraphicStroke(pSvtGraphicStroke); 1279*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 1280*cdf0e10cSrcweir impEndSvtGraphicStroke(pSvtGraphicStroke); 1281*cdf0e10cSrcweir } 1282*cdf0e10cSrcweir 1283*cdf0e10cSrcweir break; 1284*cdf0e10cSrcweir } 1285*cdf0e10cSrcweir case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D : 1286*cdf0e10cSrcweir { 1287*cdf0e10cSrcweir // direct draw of transformed BitmapEx primitive; use default processing 1288*cdf0e10cSrcweir RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate)); 1289*cdf0e10cSrcweir break; 1290*cdf0e10cSrcweir } 1291*cdf0e10cSrcweir case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D : 1292*cdf0e10cSrcweir { 1293*cdf0e10cSrcweir // direct draw of transformed RenderGraphic primitive; use default processing 1294*cdf0e10cSrcweir RenderRenderGraphicPrimitive2D(static_cast< const primitive2d::RenderGraphicPrimitive2D& >(rCandidate)); 1295*cdf0e10cSrcweir break; 1296*cdf0e10cSrcweir } 1297*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D : 1298*cdf0e10cSrcweir { 1299*cdf0e10cSrcweir // need to handle PolyPolygonBitmapPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END 1300*cdf0e10cSrcweir const primitive2d::PolyPolygonBitmapPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate); 1301*cdf0e10cSrcweir basegfx::B2DPolyPolygon aLocalPolyPolygon(rBitmapCandidate.getB2DPolyPolygon()); 1302*cdf0e10cSrcweir 1303*cdf0e10cSrcweir if(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon)) 1304*cdf0e10cSrcweir { 1305*cdf0e10cSrcweir // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points 1306*cdf0e10cSrcweir // per polygon. If there are more use the splitted polygon and call recursively 1307*cdf0e10cSrcweir const primitive2d::PolyPolygonBitmapPrimitive2D aSplitted( 1308*cdf0e10cSrcweir aLocalPolyPolygon, 1309*cdf0e10cSrcweir rBitmapCandidate.getFillBitmap()); 1310*cdf0e10cSrcweir 1311*cdf0e10cSrcweir processBasePrimitive2D(aSplitted); 1312*cdf0e10cSrcweir } 1313*cdf0e10cSrcweir else 1314*cdf0e10cSrcweir { 1315*cdf0e10cSrcweir SvtGraphicFill* pSvtGraphicFill = 0; 1316*cdf0e10cSrcweir 1317*cdf0e10cSrcweir if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count()) 1318*cdf0e10cSrcweir { 1319*cdf0e10cSrcweir aLocalPolyPolygon.transform(maCurrentTransformation); 1320*cdf0e10cSrcweir // calculate transformation. Get real object size, all values in FillBitmapAttribute 1321*cdf0e10cSrcweir // are relative to the unified object 1322*cdf0e10cSrcweir const attribute::FillBitmapAttribute& rFillBitmapAttribute = rBitmapCandidate .getFillBitmap(); 1323*cdf0e10cSrcweir const basegfx::B2DRange aOutlineRange(basegfx::tools::getRange(aLocalPolyPolygon)); 1324*cdf0e10cSrcweir const basegfx::B2DVector aOutlineSize(aOutlineRange.getRange()); 1325*cdf0e10cSrcweir 1326*cdf0e10cSrcweir // get absolute values 1327*cdf0e10cSrcweir const basegfx::B2DVector aFillBitmapSize(rFillBitmapAttribute.getSize() * aOutlineSize); 1328*cdf0e10cSrcweir const basegfx::B2DPoint aFillBitmapTopLeft(rFillBitmapAttribute.getTopLeft() * aOutlineSize); 1329*cdf0e10cSrcweir 1330*cdf0e10cSrcweir // the scaling needs scale from pixel to logic coordinate system 1331*cdf0e10cSrcweir const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx(); 1332*cdf0e10cSrcweir Size aBmpSizePixel(rBitmapEx.GetSizePixel()); 1333*cdf0e10cSrcweir 1334*cdf0e10cSrcweir if(!aBmpSizePixel.Width()) 1335*cdf0e10cSrcweir { 1336*cdf0e10cSrcweir aBmpSizePixel.Width() = 1; 1337*cdf0e10cSrcweir } 1338*cdf0e10cSrcweir 1339*cdf0e10cSrcweir if(!aBmpSizePixel.Height()) 1340*cdf0e10cSrcweir { 1341*cdf0e10cSrcweir aBmpSizePixel.Height() = 1; 1342*cdf0e10cSrcweir } 1343*cdf0e10cSrcweir 1344*cdf0e10cSrcweir // setup transformation like in impgrfll 1345*cdf0e10cSrcweir SvtGraphicFill::Transform aTransform; 1346*cdf0e10cSrcweir 1347*cdf0e10cSrcweir // scale values are divided by bitmap pixel sizes 1348*cdf0e10cSrcweir aTransform.matrix[0] = aFillBitmapSize.getX() / aBmpSizePixel.Width(); 1349*cdf0e10cSrcweir aTransform.matrix[4] = aFillBitmapSize.getY() / aBmpSizePixel.Height(); 1350*cdf0e10cSrcweir 1351*cdf0e10cSrcweir // translates are absolute 1352*cdf0e10cSrcweir aTransform.matrix[2] = aFillBitmapTopLeft.getX(); 1353*cdf0e10cSrcweir aTransform.matrix[5] = aFillBitmapTopLeft.getY(); 1354*cdf0e10cSrcweir 1355*cdf0e10cSrcweir // setup fill graphic like in impgrfll 1356*cdf0e10cSrcweir Graphic aFillGraphic = Graphic(rBitmapEx); 1357*cdf0e10cSrcweir aFillGraphic.SetPrefMapMode(MapMode(MAP_PIXEL)); 1358*cdf0e10cSrcweir aFillGraphic.SetPrefSize(aBmpSizePixel); 1359*cdf0e10cSrcweir 1360*cdf0e10cSrcweir pSvtGraphicFill = new SvtGraphicFill( 1361*cdf0e10cSrcweir PolyPolygon(aLocalPolyPolygon), 1362*cdf0e10cSrcweir Color(), 1363*cdf0e10cSrcweir 0.0, 1364*cdf0e10cSrcweir SvtGraphicFill::fillEvenOdd, 1365*cdf0e10cSrcweir SvtGraphicFill::fillTexture, 1366*cdf0e10cSrcweir aTransform, 1367*cdf0e10cSrcweir rFillBitmapAttribute.getTiling(), 1368*cdf0e10cSrcweir SvtGraphicFill::hatchSingle, 1369*cdf0e10cSrcweir Color(), 1370*cdf0e10cSrcweir SvtGraphicFill::gradientLinear, 1371*cdf0e10cSrcweir Color(), 1372*cdf0e10cSrcweir Color(), 1373*cdf0e10cSrcweir 0, 1374*cdf0e10cSrcweir aFillGraphic); 1375*cdf0e10cSrcweir } 1376*cdf0e10cSrcweir 1377*cdf0e10cSrcweir // Do use decomposition; encapsulate with SvtGraphicFill 1378*cdf0e10cSrcweir impStartSvtGraphicFill(pSvtGraphicFill); 1379*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 1380*cdf0e10cSrcweir impEndSvtGraphicFill(pSvtGraphicFill); 1381*cdf0e10cSrcweir } 1382*cdf0e10cSrcweir 1383*cdf0e10cSrcweir break; 1384*cdf0e10cSrcweir } 1385*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D : 1386*cdf0e10cSrcweir { 1387*cdf0e10cSrcweir // need to handle PolyPolygonHatchPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END 1388*cdf0e10cSrcweir const primitive2d::PolyPolygonHatchPrimitive2D& rHatchCandidate = static_cast< const primitive2d::PolyPolygonHatchPrimitive2D& >(rCandidate); 1389*cdf0e10cSrcweir const attribute::FillHatchAttribute& rFillHatchAttribute = rHatchCandidate.getFillHatch(); 1390*cdf0e10cSrcweir basegfx::B2DPolyPolygon aLocalPolyPolygon(rHatchCandidate.getB2DPolyPolygon()); 1391*cdf0e10cSrcweir 1392*cdf0e10cSrcweir // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points 1393*cdf0e10cSrcweir // per polygon. Split polygon until there are less than that 1394*cdf0e10cSrcweir while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon)) 1395*cdf0e10cSrcweir ; 1396*cdf0e10cSrcweir 1397*cdf0e10cSrcweir if(rFillHatchAttribute.isFillBackground()) 1398*cdf0e10cSrcweir { 1399*cdf0e10cSrcweir // with fixing #i111954# (see below) the possible background 1400*cdf0e10cSrcweir // fill of a hatched object was lost.Generate a background fill 1401*cdf0e10cSrcweir // primitive and render it 1402*cdf0e10cSrcweir const primitive2d::Primitive2DReference xBackground( 1403*cdf0e10cSrcweir new primitive2d::PolyPolygonColorPrimitive2D( 1404*cdf0e10cSrcweir aLocalPolyPolygon, 1405*cdf0e10cSrcweir rHatchCandidate.getBackgroundColor())); 1406*cdf0e10cSrcweir 1407*cdf0e10cSrcweir process(primitive2d::Primitive2DSequence(&xBackground, 1)); 1408*cdf0e10cSrcweir } 1409*cdf0e10cSrcweir 1410*cdf0e10cSrcweir SvtGraphicFill* pSvtGraphicFill = 0; 1411*cdf0e10cSrcweir aLocalPolyPolygon.transform(maCurrentTransformation); 1412*cdf0e10cSrcweir 1413*cdf0e10cSrcweir if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count()) 1414*cdf0e10cSrcweir { 1415*cdf0e10cSrcweir // re-create a VCL hatch as base data 1416*cdf0e10cSrcweir SvtGraphicFill::HatchType eHatch(SvtGraphicFill::hatchSingle); 1417*cdf0e10cSrcweir 1418*cdf0e10cSrcweir switch(rFillHatchAttribute.getStyle()) 1419*cdf0e10cSrcweir { 1420*cdf0e10cSrcweir default: // attribute::HATCHSTYLE_SINGLE : 1421*cdf0e10cSrcweir { 1422*cdf0e10cSrcweir eHatch = SvtGraphicFill::hatchSingle; 1423*cdf0e10cSrcweir break; 1424*cdf0e10cSrcweir } 1425*cdf0e10cSrcweir case attribute::HATCHSTYLE_DOUBLE : 1426*cdf0e10cSrcweir { 1427*cdf0e10cSrcweir eHatch = SvtGraphicFill::hatchDouble; 1428*cdf0e10cSrcweir break; 1429*cdf0e10cSrcweir } 1430*cdf0e10cSrcweir case attribute::HATCHSTYLE_TRIPLE : 1431*cdf0e10cSrcweir { 1432*cdf0e10cSrcweir eHatch = SvtGraphicFill::hatchTriple; 1433*cdf0e10cSrcweir break; 1434*cdf0e10cSrcweir } 1435*cdf0e10cSrcweir } 1436*cdf0e10cSrcweir 1437*cdf0e10cSrcweir SvtGraphicFill::Transform aTransform; 1438*cdf0e10cSrcweir 1439*cdf0e10cSrcweir // scale 1440*cdf0e10cSrcweir aTransform.matrix[0] *= rFillHatchAttribute.getDistance(); 1441*cdf0e10cSrcweir aTransform.matrix[4] *= rFillHatchAttribute.getDistance(); 1442*cdf0e10cSrcweir 1443*cdf0e10cSrcweir // rotate (was never correct in impgrfll anyways, use correct angle now) 1444*cdf0e10cSrcweir aTransform.matrix[0] *= cos(rFillHatchAttribute.getAngle()); 1445*cdf0e10cSrcweir aTransform.matrix[1] *= -sin(rFillHatchAttribute.getAngle()); 1446*cdf0e10cSrcweir aTransform.matrix[3] *= sin(rFillHatchAttribute.getAngle()); 1447*cdf0e10cSrcweir aTransform.matrix[4] *= cos(rFillHatchAttribute.getAngle()); 1448*cdf0e10cSrcweir 1449*cdf0e10cSrcweir pSvtGraphicFill = new SvtGraphicFill( 1450*cdf0e10cSrcweir PolyPolygon(aLocalPolyPolygon), 1451*cdf0e10cSrcweir Color(), 1452*cdf0e10cSrcweir 0.0, 1453*cdf0e10cSrcweir SvtGraphicFill::fillEvenOdd, 1454*cdf0e10cSrcweir SvtGraphicFill::fillHatch, 1455*cdf0e10cSrcweir aTransform, 1456*cdf0e10cSrcweir false, 1457*cdf0e10cSrcweir eHatch, 1458*cdf0e10cSrcweir Color(rFillHatchAttribute.getColor()), 1459*cdf0e10cSrcweir SvtGraphicFill::gradientLinear, 1460*cdf0e10cSrcweir Color(), 1461*cdf0e10cSrcweir Color(), 1462*cdf0e10cSrcweir 0, 1463*cdf0e10cSrcweir Graphic()); 1464*cdf0e10cSrcweir } 1465*cdf0e10cSrcweir 1466*cdf0e10cSrcweir // Do use decomposition; encapsulate with SvtGraphicFill 1467*cdf0e10cSrcweir impStartSvtGraphicFill(pSvtGraphicFill); 1468*cdf0e10cSrcweir 1469*cdf0e10cSrcweir // #i111954# do NOT use decomposition, but use direct VCL-command 1470*cdf0e10cSrcweir // process(rCandidate.get2DDecomposition(getViewInformation2D())); 1471*cdf0e10cSrcweir const PolyPolygon aToolsPolyPolygon(aLocalPolyPolygon); 1472*cdf0e10cSrcweir const HatchStyle aHatchStyle( 1473*cdf0e10cSrcweir attribute::HATCHSTYLE_SINGLE == rFillHatchAttribute.getStyle() ? HATCH_SINGLE : 1474*cdf0e10cSrcweir attribute::HATCHSTYLE_DOUBLE == rFillHatchAttribute.getStyle() ? HATCH_DOUBLE : 1475*cdf0e10cSrcweir HATCH_TRIPLE); 1476*cdf0e10cSrcweir 1477*cdf0e10cSrcweir mpOutputDevice->DrawHatch(aToolsPolyPolygon, 1478*cdf0e10cSrcweir Hatch(aHatchStyle, 1479*cdf0e10cSrcweir Color(rFillHatchAttribute.getColor()), 1480*cdf0e10cSrcweir basegfx::fround(rFillHatchAttribute.getDistance()), 1481*cdf0e10cSrcweir basegfx::fround(rFillHatchAttribute.getAngle() / F_PI1800))); 1482*cdf0e10cSrcweir 1483*cdf0e10cSrcweir impEndSvtGraphicFill(pSvtGraphicFill); 1484*cdf0e10cSrcweir 1485*cdf0e10cSrcweir break; 1486*cdf0e10cSrcweir } 1487*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D : 1488*cdf0e10cSrcweir { 1489*cdf0e10cSrcweir const primitive2d::PolyPolygonGradientPrimitive2D& rGradientCandidate = static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate); 1490*cdf0e10cSrcweir basegfx::B2DPolyPolygon aLocalPolyPolygon(rGradientCandidate.getB2DPolyPolygon()); 1491*cdf0e10cSrcweir 1492*cdf0e10cSrcweir // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points 1493*cdf0e10cSrcweir // per polygon. Split polygon until there are less than that 1494*cdf0e10cSrcweir while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon)) 1495*cdf0e10cSrcweir ; 1496*cdf0e10cSrcweir 1497*cdf0e10cSrcweir // for support of MetaCommentActions of the form XGRAD_SEQ_BEGIN, XGRAD_SEQ_END 1498*cdf0e10cSrcweir // it is safest to use the VCL OutputDevice::DrawGradient method which creates those. 1499*cdf0e10cSrcweir // re-create a VCL-gradient from FillGradientPrimitive2D and the needed tools PolyPolygon 1500*cdf0e10cSrcweir Gradient aVCLGradient; 1501*cdf0e10cSrcweir impConvertFillGradientAttributeToVCLGradient(aVCLGradient, rGradientCandidate.getFillGradient(), false); 1502*cdf0e10cSrcweir aLocalPolyPolygon.transform(maCurrentTransformation); 1503*cdf0e10cSrcweir 1504*cdf0e10cSrcweir // #i82145# ATM VCL printing of gradients using curved shapes does not work, 1505*cdf0e10cSrcweir // i submitted the bug with the given ID to THB. When that task is fixed it is 1506*cdf0e10cSrcweir // necessary to again remove this subdivision since it decreases possible 1507*cdf0e10cSrcweir // printing quality (not even resolution-dependent for now). THB will tell 1508*cdf0e10cSrcweir // me when that task is fixed in the master 1509*cdf0e10cSrcweir const PolyPolygon aToolsPolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(aLocalPolyPolygon)); 1510*cdf0e10cSrcweir 1511*cdf0e10cSrcweir // XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support 1512*cdf0e10cSrcweir SvtGraphicFill* pSvtGraphicFill = 0; 1513*cdf0e10cSrcweir 1514*cdf0e10cSrcweir if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count()) 1515*cdf0e10cSrcweir { 1516*cdf0e10cSrcweir // setup gradient stuff like in like in impgrfll 1517*cdf0e10cSrcweir SvtGraphicFill::GradientType eGrad(SvtGraphicFill::gradientLinear); 1518*cdf0e10cSrcweir 1519*cdf0e10cSrcweir switch(aVCLGradient.GetStyle()) 1520*cdf0e10cSrcweir { 1521*cdf0e10cSrcweir default : // GRADIENT_LINEAR: 1522*cdf0e10cSrcweir case GRADIENT_AXIAL: 1523*cdf0e10cSrcweir eGrad = SvtGraphicFill::gradientLinear; 1524*cdf0e10cSrcweir break; 1525*cdf0e10cSrcweir case GRADIENT_RADIAL: 1526*cdf0e10cSrcweir case GRADIENT_ELLIPTICAL: 1527*cdf0e10cSrcweir eGrad = SvtGraphicFill::gradientRadial; 1528*cdf0e10cSrcweir break; 1529*cdf0e10cSrcweir case GRADIENT_SQUARE: 1530*cdf0e10cSrcweir case GRADIENT_RECT: 1531*cdf0e10cSrcweir eGrad = SvtGraphicFill::gradientRectangular; 1532*cdf0e10cSrcweir break; 1533*cdf0e10cSrcweir } 1534*cdf0e10cSrcweir 1535*cdf0e10cSrcweir pSvtGraphicFill = new SvtGraphicFill( 1536*cdf0e10cSrcweir aToolsPolyPolygon, 1537*cdf0e10cSrcweir Color(), 1538*cdf0e10cSrcweir 0.0, 1539*cdf0e10cSrcweir SvtGraphicFill::fillEvenOdd, 1540*cdf0e10cSrcweir SvtGraphicFill::fillGradient, 1541*cdf0e10cSrcweir SvtGraphicFill::Transform(), 1542*cdf0e10cSrcweir false, 1543*cdf0e10cSrcweir SvtGraphicFill::hatchSingle, 1544*cdf0e10cSrcweir Color(), 1545*cdf0e10cSrcweir eGrad, 1546*cdf0e10cSrcweir aVCLGradient.GetStartColor(), 1547*cdf0e10cSrcweir aVCLGradient.GetEndColor(), 1548*cdf0e10cSrcweir aVCLGradient.GetSteps(), 1549*cdf0e10cSrcweir Graphic()); 1550*cdf0e10cSrcweir } 1551*cdf0e10cSrcweir 1552*cdf0e10cSrcweir // call VCL directly; encapsulate with SvtGraphicFill 1553*cdf0e10cSrcweir impStartSvtGraphicFill(pSvtGraphicFill); 1554*cdf0e10cSrcweir mpOutputDevice->DrawGradient(aToolsPolyPolygon, aVCLGradient); 1555*cdf0e10cSrcweir impEndSvtGraphicFill(pSvtGraphicFill); 1556*cdf0e10cSrcweir 1557*cdf0e10cSrcweir // NO usage of common own gradient randerer, not used ATM for VCL MetaFile, see text above 1558*cdf0e10cSrcweir // RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate)); 1559*cdf0e10cSrcweir 1560*cdf0e10cSrcweir break; 1561*cdf0e10cSrcweir } 1562*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D : 1563*cdf0e10cSrcweir { 1564*cdf0e10cSrcweir const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate(static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate)); 1565*cdf0e10cSrcweir basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon()); 1566*cdf0e10cSrcweir 1567*cdf0e10cSrcweir // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points 1568*cdf0e10cSrcweir // per polygon. Split polygon until there are less than that 1569*cdf0e10cSrcweir while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon)) 1570*cdf0e10cSrcweir ; 1571*cdf0e10cSrcweir 1572*cdf0e10cSrcweir const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor())); 1573*cdf0e10cSrcweir aLocalPolyPolygon.transform(maCurrentTransformation); 1574*cdf0e10cSrcweir 1575*cdf0e10cSrcweir // XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support 1576*cdf0e10cSrcweir SvtGraphicFill* pSvtGraphicFill = 0; 1577*cdf0e10cSrcweir 1578*cdf0e10cSrcweir if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count()) 1579*cdf0e10cSrcweir { 1580*cdf0e10cSrcweir // setup simple color fill stuff like in impgrfll 1581*cdf0e10cSrcweir pSvtGraphicFill = new SvtGraphicFill( 1582*cdf0e10cSrcweir PolyPolygon(aLocalPolyPolygon), 1583*cdf0e10cSrcweir Color(aPolygonColor), 1584*cdf0e10cSrcweir 0.0, 1585*cdf0e10cSrcweir SvtGraphicFill::fillEvenOdd, 1586*cdf0e10cSrcweir SvtGraphicFill::fillSolid, 1587*cdf0e10cSrcweir SvtGraphicFill::Transform(), 1588*cdf0e10cSrcweir false, 1589*cdf0e10cSrcweir SvtGraphicFill::hatchSingle, 1590*cdf0e10cSrcweir Color(), 1591*cdf0e10cSrcweir SvtGraphicFill::gradientLinear, 1592*cdf0e10cSrcweir Color(), 1593*cdf0e10cSrcweir Color(), 1594*cdf0e10cSrcweir 0, 1595*cdf0e10cSrcweir Graphic()); 1596*cdf0e10cSrcweir } 1597*cdf0e10cSrcweir 1598*cdf0e10cSrcweir // set line and fill color 1599*cdf0e10cSrcweir mpOutputDevice->SetFillColor(Color(aPolygonColor)); 1600*cdf0e10cSrcweir mpOutputDevice->SetLineColor(); 1601*cdf0e10cSrcweir 1602*cdf0e10cSrcweir // call VCL directly; encapsulate with SvtGraphicFill 1603*cdf0e10cSrcweir impStartSvtGraphicFill(pSvtGraphicFill); 1604*cdf0e10cSrcweir mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); 1605*cdf0e10cSrcweir impEndSvtGraphicFill(pSvtGraphicFill); 1606*cdf0e10cSrcweir 1607*cdf0e10cSrcweir break; 1608*cdf0e10cSrcweir } 1609*cdf0e10cSrcweir case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D : 1610*cdf0e10cSrcweir { 1611*cdf0e10cSrcweir // direct draw of MetaFile, use default pocessing 1612*cdf0e10cSrcweir RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate)); 1613*cdf0e10cSrcweir break; 1614*cdf0e10cSrcweir } 1615*cdf0e10cSrcweir case PRIMITIVE2D_ID_MASKPRIMITIVE2D : 1616*cdf0e10cSrcweir { 1617*cdf0e10cSrcweir // mask group. Special handling for MetaFiles. 1618*cdf0e10cSrcweir const primitive2d::MaskPrimitive2D& rMaskCandidate = static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate); 1619*cdf0e10cSrcweir 1620*cdf0e10cSrcweir if(rMaskCandidate.getChildren().hasElements()) 1621*cdf0e10cSrcweir { 1622*cdf0e10cSrcweir basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask()); 1623*cdf0e10cSrcweir 1624*cdf0e10cSrcweir if(aMask.count()) 1625*cdf0e10cSrcweir { 1626*cdf0e10cSrcweir // prepare new mask polygon and rescue current one 1627*cdf0e10cSrcweir aMask.transform(maCurrentTransformation); 1628*cdf0e10cSrcweir const basegfx::B2DPolyPolygon aLastClipPolyPolygon(maClipPolyPolygon); 1629*cdf0e10cSrcweir 1630*cdf0e10cSrcweir if(maClipPolyPolygon.count()) 1631*cdf0e10cSrcweir { 1632*cdf0e10cSrcweir // there is already a clip polygon set; build clipped union of 1633*cdf0e10cSrcweir // current mask polygon and new one 1634*cdf0e10cSrcweir maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon( 1635*cdf0e10cSrcweir aMask, 1636*cdf0e10cSrcweir maClipPolyPolygon, 1637*cdf0e10cSrcweir true, // #i106516# we want the inside of aMask, not the outside 1638*cdf0e10cSrcweir false); 1639*cdf0e10cSrcweir } 1640*cdf0e10cSrcweir else 1641*cdf0e10cSrcweir { 1642*cdf0e10cSrcweir // use mask directly 1643*cdf0e10cSrcweir maClipPolyPolygon = aMask; 1644*cdf0e10cSrcweir } 1645*cdf0e10cSrcweir 1646*cdf0e10cSrcweir if(maClipPolyPolygon.count()) 1647*cdf0e10cSrcweir { 1648*cdf0e10cSrcweir // set VCL clip region; subdivide before conversion to tools polygon. Subdivision necessary (!) 1649*cdf0e10cSrcweir // Removed subdivision and fixed in Region::ImplPolyPolyRegionToBandRegionFunc() in VCL where 1650*cdf0e10cSrcweir // the ClipRegion is built from the Polygon. A AdaptiveSubdivide on the source polygon was missing there 1651*cdf0e10cSrcweir mpOutputDevice->Push(PUSH_CLIPREGION); 1652*cdf0e10cSrcweir //mpOutputDevice->SetClipRegion(Region(PolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(maClipPolyPolygon)))); 1653*cdf0e10cSrcweir mpOutputDevice->SetClipRegion(Region(PolyPolygon(maClipPolyPolygon))); 1654*cdf0e10cSrcweir } 1655*cdf0e10cSrcweir 1656*cdf0e10cSrcweir // recursively paint content 1657*cdf0e10cSrcweir process(rMaskCandidate.getChildren()); 1658*cdf0e10cSrcweir 1659*cdf0e10cSrcweir if(maClipPolyPolygon.count()) 1660*cdf0e10cSrcweir { 1661*cdf0e10cSrcweir // restore VCL clip region 1662*cdf0e10cSrcweir mpOutputDevice->Pop(); 1663*cdf0e10cSrcweir } 1664*cdf0e10cSrcweir 1665*cdf0e10cSrcweir // restore to rescued clip polygon 1666*cdf0e10cSrcweir maClipPolyPolygon = aLastClipPolyPolygon; 1667*cdf0e10cSrcweir } 1668*cdf0e10cSrcweir else 1669*cdf0e10cSrcweir { 1670*cdf0e10cSrcweir // no mask, no clipping. recursively paint content 1671*cdf0e10cSrcweir process(rMaskCandidate.getChildren()); 1672*cdf0e10cSrcweir } 1673*cdf0e10cSrcweir } 1674*cdf0e10cSrcweir 1675*cdf0e10cSrcweir break; 1676*cdf0e10cSrcweir } 1677*cdf0e10cSrcweir case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D : 1678*cdf0e10cSrcweir { 1679*cdf0e10cSrcweir // modified color group. Force output to unified color. Use default pocessing. 1680*cdf0e10cSrcweir RenderModifiedColorPrimitive2D(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate)); 1681*cdf0e10cSrcweir break; 1682*cdf0e10cSrcweir } 1683*cdf0e10cSrcweir case PRIMITIVE2D_ID_HIDDENGEOMETRYPRIMITIVE2D : 1684*cdf0e10cSrcweir { 1685*cdf0e10cSrcweir // HiddenGeometryPrimitive2D; to rebuilt the old MetaFile creation, it is necessary to 1686*cdf0e10cSrcweir // not ignore them (as it was thought), but to add a MetaFile entry for them. 1687*cdf0e10cSrcweir basegfx::B2DRange aInvisibleRange(rCandidate.getB2DRange(getViewInformation2D())); 1688*cdf0e10cSrcweir 1689*cdf0e10cSrcweir if(!aInvisibleRange.isEmpty()) 1690*cdf0e10cSrcweir { 1691*cdf0e10cSrcweir aInvisibleRange.transform(maCurrentTransformation); 1692*cdf0e10cSrcweir const Rectangle aRectLogic( 1693*cdf0e10cSrcweir (sal_Int32)floor(aInvisibleRange.getMinX()), (sal_Int32)floor(aInvisibleRange.getMinY()), 1694*cdf0e10cSrcweir (sal_Int32)ceil(aInvisibleRange.getMaxX()), (sal_Int32)ceil(aInvisibleRange.getMaxY())); 1695*cdf0e10cSrcweir 1696*cdf0e10cSrcweir mpOutputDevice->SetFillColor(); 1697*cdf0e10cSrcweir mpOutputDevice->SetLineColor(); 1698*cdf0e10cSrcweir mpOutputDevice->DrawRect(aRectLogic); 1699*cdf0e10cSrcweir } 1700*cdf0e10cSrcweir 1701*cdf0e10cSrcweir break; 1702*cdf0e10cSrcweir } 1703*cdf0e10cSrcweir case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D : 1704*cdf0e10cSrcweir { 1705*cdf0e10cSrcweir // for metafile: Need to examine what the pure vcl version is doing here actually 1706*cdf0e10cSrcweir // - uses DrawTransparent with metafile for content and a gradient 1707*cdf0e10cSrcweir // - uses DrawTransparent for single PolyPoylgons directly. Can be detected by 1708*cdf0e10cSrcweir // checking the content for single PolyPolygonColorPrimitive2D 1709*cdf0e10cSrcweir const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate); 1710*cdf0e10cSrcweir const primitive2d::Primitive2DSequence rContent = rUniTransparenceCandidate.getChildren(); 1711*cdf0e10cSrcweir 1712*cdf0e10cSrcweir if(rContent.hasElements()) 1713*cdf0e10cSrcweir { 1714*cdf0e10cSrcweir if(0.0 == rUniTransparenceCandidate.getTransparence()) 1715*cdf0e10cSrcweir { 1716*cdf0e10cSrcweir // not transparent at all, use content 1717*cdf0e10cSrcweir process(rUniTransparenceCandidate.getChildren()); 1718*cdf0e10cSrcweir } 1719*cdf0e10cSrcweir else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0) 1720*cdf0e10cSrcweir { 1721*cdf0e10cSrcweir // try to identify a single PolyPolygonColorPrimitive2D in the 1722*cdf0e10cSrcweir // content part of the transparence primitive 1723*cdf0e10cSrcweir const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = 0; 1724*cdf0e10cSrcweir static bool bForceToMetafile(false); 1725*cdf0e10cSrcweir 1726*cdf0e10cSrcweir if(!bForceToMetafile && 1 == rContent.getLength()) 1727*cdf0e10cSrcweir { 1728*cdf0e10cSrcweir const primitive2d::Primitive2DReference xReference(rContent[0]); 1729*cdf0e10cSrcweir pPoPoColor = dynamic_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(xReference.get()); 1730*cdf0e10cSrcweir } 1731*cdf0e10cSrcweir 1732*cdf0e10cSrcweir // PolyPolygonGradientPrimitive2D, PolyPolygonHatchPrimitive2D and 1733*cdf0e10cSrcweir // PolyPolygonBitmapPrimitive2D are derived from PolyPolygonColorPrimitive2D. 1734*cdf0e10cSrcweir // Check also for correct ID to exclude derived implementations 1735*cdf0e10cSrcweir if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID()) 1736*cdf0e10cSrcweir { 1737*cdf0e10cSrcweir // single transparent PolyPolygon identified, use directly 1738*cdf0e10cSrcweir const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); 1739*cdf0e10cSrcweir basegfx::B2DPolyPolygon aLocalPolyPolygon(pPoPoColor->getB2DPolyPolygon()); 1740*cdf0e10cSrcweir 1741*cdf0e10cSrcweir // #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points 1742*cdf0e10cSrcweir // per polygon. Split polygon until there are less than that 1743*cdf0e10cSrcweir while(fillPolyPolygonNeededToBeSplit(aLocalPolyPolygon)) 1744*cdf0e10cSrcweir ; 1745*cdf0e10cSrcweir 1746*cdf0e10cSrcweir // now transform 1747*cdf0e10cSrcweir aLocalPolyPolygon.transform(maCurrentTransformation); 1748*cdf0e10cSrcweir 1749*cdf0e10cSrcweir // XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support 1750*cdf0e10cSrcweir SvtGraphicFill* pSvtGraphicFill = 0; 1751*cdf0e10cSrcweir 1752*cdf0e10cSrcweir if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count()) 1753*cdf0e10cSrcweir { 1754*cdf0e10cSrcweir // setup simple color with transparence fill stuff like in impgrfll 1755*cdf0e10cSrcweir pSvtGraphicFill = new SvtGraphicFill( 1756*cdf0e10cSrcweir PolyPolygon(aLocalPolyPolygon), 1757*cdf0e10cSrcweir Color(aPolygonColor), 1758*cdf0e10cSrcweir rUniTransparenceCandidate.getTransparence(), 1759*cdf0e10cSrcweir SvtGraphicFill::fillEvenOdd, 1760*cdf0e10cSrcweir SvtGraphicFill::fillSolid, 1761*cdf0e10cSrcweir SvtGraphicFill::Transform(), 1762*cdf0e10cSrcweir false, 1763*cdf0e10cSrcweir SvtGraphicFill::hatchSingle, 1764*cdf0e10cSrcweir Color(), 1765*cdf0e10cSrcweir SvtGraphicFill::gradientLinear, 1766*cdf0e10cSrcweir Color(), 1767*cdf0e10cSrcweir Color(), 1768*cdf0e10cSrcweir 0, 1769*cdf0e10cSrcweir Graphic()); 1770*cdf0e10cSrcweir } 1771*cdf0e10cSrcweir 1772*cdf0e10cSrcweir // set line and fill color 1773*cdf0e10cSrcweir const sal_uInt16 nTransPercentVcl((sal_uInt16)basegfx::fround(rUniTransparenceCandidate.getTransparence() * 100.0)); 1774*cdf0e10cSrcweir mpOutputDevice->SetFillColor(Color(aPolygonColor)); 1775*cdf0e10cSrcweir mpOutputDevice->SetLineColor(); 1776*cdf0e10cSrcweir 1777*cdf0e10cSrcweir // call VCL directly; encapsulate with SvtGraphicFill 1778*cdf0e10cSrcweir impStartSvtGraphicFill(pSvtGraphicFill); 1779*cdf0e10cSrcweir mpOutputDevice->DrawTransparent( 1780*cdf0e10cSrcweir PolyPolygon(aLocalPolyPolygon), 1781*cdf0e10cSrcweir nTransPercentVcl); 1782*cdf0e10cSrcweir impEndSvtGraphicFill(pSvtGraphicFill); 1783*cdf0e10cSrcweir } 1784*cdf0e10cSrcweir else 1785*cdf0e10cSrcweir { 1786*cdf0e10cSrcweir // svae old mfCurrentUnifiedTransparence and set new one 1787*cdf0e10cSrcweir // so that contained SvtGraphicStroke may use the current one 1788*cdf0e10cSrcweir const double fLastCurrentUnifiedTransparence(mfCurrentUnifiedTransparence); 1789*cdf0e10cSrcweir // #i105377# paint the content metafile opaque as the transparency gets 1790*cdf0e10cSrcweir // split of into the gradient below 1791*cdf0e10cSrcweir // mfCurrentUnifiedTransparence = rUniTransparenceCandidate.getTransparence(); 1792*cdf0e10cSrcweir mfCurrentUnifiedTransparence = 0; 1793*cdf0e10cSrcweir 1794*cdf0e10cSrcweir // various content, create content-metafile 1795*cdf0e10cSrcweir GDIMetaFile aContentMetafile; 1796*cdf0e10cSrcweir const Rectangle aPrimitiveRectangle(impDumpToMetaFile(rContent, aContentMetafile)); 1797*cdf0e10cSrcweir 1798*cdf0e10cSrcweir // restore mfCurrentUnifiedTransparence; it may have been used 1799*cdf0e10cSrcweir // while processing the sub-content in impDumpToMetaFile 1800*cdf0e10cSrcweir mfCurrentUnifiedTransparence = fLastCurrentUnifiedTransparence; 1801*cdf0e10cSrcweir 1802*cdf0e10cSrcweir // create uniform VCL gradient for uniform transparency 1803*cdf0e10cSrcweir Gradient aVCLGradient; 1804*cdf0e10cSrcweir const sal_uInt8 nTransPercentVcl((sal_uInt8)basegfx::fround(rUniTransparenceCandidate.getTransparence() * 255.0)); 1805*cdf0e10cSrcweir const Color aTransColor(nTransPercentVcl, nTransPercentVcl, nTransPercentVcl); 1806*cdf0e10cSrcweir 1807*cdf0e10cSrcweir aVCLGradient.SetStyle(GRADIENT_LINEAR); 1808*cdf0e10cSrcweir aVCLGradient.SetStartColor(aTransColor); 1809*cdf0e10cSrcweir aVCLGradient.SetEndColor(aTransColor); 1810*cdf0e10cSrcweir aVCLGradient.SetAngle(0); 1811*cdf0e10cSrcweir aVCLGradient.SetBorder(0); 1812*cdf0e10cSrcweir aVCLGradient.SetOfsX(0); 1813*cdf0e10cSrcweir aVCLGradient.SetOfsY(0); 1814*cdf0e10cSrcweir aVCLGradient.SetStartIntensity(100); 1815*cdf0e10cSrcweir aVCLGradient.SetEndIntensity(100); 1816*cdf0e10cSrcweir aVCLGradient.SetSteps(2); 1817*cdf0e10cSrcweir 1818*cdf0e10cSrcweir // render it to VCL 1819*cdf0e10cSrcweir mpOutputDevice->DrawTransparent( 1820*cdf0e10cSrcweir aContentMetafile, aPrimitiveRectangle.TopLeft(), 1821*cdf0e10cSrcweir aPrimitiveRectangle.GetSize(), aVCLGradient); 1822*cdf0e10cSrcweir } 1823*cdf0e10cSrcweir } 1824*cdf0e10cSrcweir } 1825*cdf0e10cSrcweir 1826*cdf0e10cSrcweir break; 1827*cdf0e10cSrcweir } 1828*cdf0e10cSrcweir case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D : 1829*cdf0e10cSrcweir { 1830*cdf0e10cSrcweir // for metafile: Need to examine what the pure vcl version is doing here actually 1831*cdf0e10cSrcweir // - uses DrawTransparent with metafile for content and a gradient 1832*cdf0e10cSrcweir // i can detect this here with checking the gradient part for a single 1833*cdf0e10cSrcweir // FillGradientPrimitive2D and reconstruct the gradient. 1834*cdf0e10cSrcweir // If that detection goes wrong, i have to create an transparence-blended bitmap. Eventually 1835*cdf0e10cSrcweir // do that in stripes, else RenderTransparencePrimitive2D may just be used 1836*cdf0e10cSrcweir const primitive2d::TransparencePrimitive2D& rTransparenceCandidate = static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate); 1837*cdf0e10cSrcweir const primitive2d::Primitive2DSequence rContent = rTransparenceCandidate.getChildren(); 1838*cdf0e10cSrcweir const primitive2d::Primitive2DSequence rTransparence = rTransparenceCandidate.getTransparence(); 1839*cdf0e10cSrcweir 1840*cdf0e10cSrcweir if(rContent.hasElements() && rTransparence.hasElements()) 1841*cdf0e10cSrcweir { 1842*cdf0e10cSrcweir // try to identify a single FillGradientPrimitive2D in the 1843*cdf0e10cSrcweir // transparence part of the primitive 1844*cdf0e10cSrcweir const primitive2d::FillGradientPrimitive2D* pFiGradient = 0; 1845*cdf0e10cSrcweir static bool bForceToBigTransparentVDev(false); 1846*cdf0e10cSrcweir 1847*cdf0e10cSrcweir if(!bForceToBigTransparentVDev && 1 == rTransparence.getLength()) 1848*cdf0e10cSrcweir { 1849*cdf0e10cSrcweir const primitive2d::Primitive2DReference xReference(rTransparence[0]); 1850*cdf0e10cSrcweir pFiGradient = dynamic_cast< const primitive2d::FillGradientPrimitive2D* >(xReference.get()); 1851*cdf0e10cSrcweir } 1852*cdf0e10cSrcweir 1853*cdf0e10cSrcweir // Check also for correct ID to exclude derived implementations 1854*cdf0e10cSrcweir if(pFiGradient && PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D == pFiGradient->getPrimitive2DID()) 1855*cdf0e10cSrcweir { 1856*cdf0e10cSrcweir // various content, create content-metafile 1857*cdf0e10cSrcweir GDIMetaFile aContentMetafile; 1858*cdf0e10cSrcweir const Rectangle aPrimitiveRectangle(impDumpToMetaFile(rContent, aContentMetafile)); 1859*cdf0e10cSrcweir 1860*cdf0e10cSrcweir // re-create a VCL-gradient from FillGradientPrimitive2D 1861*cdf0e10cSrcweir Gradient aVCLGradient; 1862*cdf0e10cSrcweir impConvertFillGradientAttributeToVCLGradient(aVCLGradient, pFiGradient->getFillGradient(), true); 1863*cdf0e10cSrcweir 1864*cdf0e10cSrcweir // render it to VCL 1865*cdf0e10cSrcweir mpOutputDevice->DrawTransparent( 1866*cdf0e10cSrcweir aContentMetafile, aPrimitiveRectangle.TopLeft(), 1867*cdf0e10cSrcweir aPrimitiveRectangle.GetSize(), aVCLGradient); 1868*cdf0e10cSrcweir } 1869*cdf0e10cSrcweir else 1870*cdf0e10cSrcweir { 1871*cdf0e10cSrcweir // sub-transparence group. Draw to VDev first. 1872*cdf0e10cSrcweir // this may get refined to tiling when resolution is too big here 1873*cdf0e10cSrcweir 1874*cdf0e10cSrcweir // need to avoid switching off MapMode stuff here; maybe need another 1875*cdf0e10cSrcweir // tooling class, cannot just do the same as with the pixel renderer. 1876*cdf0e10cSrcweir // Need to experiment... 1877*cdf0e10cSrcweir 1878*cdf0e10cSrcweir // Okay, basic implementation finished and tested. The DPI stuff was hard 1879*cdf0e10cSrcweir // and not easy to find out that it's needed. 1880*cdf0e10cSrcweir // Since this will not yet happen normally (as long as noone constructs 1881*cdf0e10cSrcweir // transparence primitives with non-trivial transparence content) i will for now not 1882*cdf0e10cSrcweir // refine to tiling here. 1883*cdf0e10cSrcweir 1884*cdf0e10cSrcweir basegfx::B2DRange aViewRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rContent, getViewInformation2D())); 1885*cdf0e10cSrcweir aViewRange.transform(maCurrentTransformation); 1886*cdf0e10cSrcweir const Rectangle aRectLogic( 1887*cdf0e10cSrcweir (sal_Int32)floor(aViewRange.getMinX()), (sal_Int32)floor(aViewRange.getMinY()), 1888*cdf0e10cSrcweir (sal_Int32)ceil(aViewRange.getMaxX()), (sal_Int32)ceil(aViewRange.getMaxY())); 1889*cdf0e10cSrcweir const Rectangle aRectPixel(mpOutputDevice->LogicToPixel(aRectLogic)); 1890*cdf0e10cSrcweir const Size aSizePixel(aRectPixel.GetSize()); 1891*cdf0e10cSrcweir const Point aEmptyPoint; 1892*cdf0e10cSrcweir VirtualDevice aBufferDevice; 1893*cdf0e10cSrcweir 1894*cdf0e10cSrcweir if(aBufferDevice.SetOutputSizePixel(aSizePixel)) 1895*cdf0e10cSrcweir { 1896*cdf0e10cSrcweir // create and set MapModes for target devices 1897*cdf0e10cSrcweir MapMode aNewMapMode(mpOutputDevice->GetMapMode()); 1898*cdf0e10cSrcweir aNewMapMode.SetOrigin(Point(-aRectLogic.Left(), -aRectLogic.Top())); 1899*cdf0e10cSrcweir aBufferDevice.SetMapMode(aNewMapMode); 1900*cdf0e10cSrcweir 1901*cdf0e10cSrcweir // prepare view transformation for target renderers 1902*cdf0e10cSrcweir // ATTENTION! Need to apply another scaling because of the potential DPI differences 1903*cdf0e10cSrcweir // between Printer and VDev (mpOutputDevice and aBufferDevice here). 1904*cdf0e10cSrcweir // To get the DPI, LogicToPixel from (1,1) from MAP_INCH needs to be used. 1905*cdf0e10cSrcweir basegfx::B2DHomMatrix aViewTransform(aBufferDevice.GetViewTransformation()); 1906*cdf0e10cSrcweir const Size aDPIOld(mpOutputDevice->LogicToPixel(Size(1, 1), MAP_INCH)); 1907*cdf0e10cSrcweir const Size aDPINew(aBufferDevice.LogicToPixel(Size(1, 1), MAP_INCH)); 1908*cdf0e10cSrcweir const double fDPIXChange((double)aDPIOld.getWidth() / (double)aDPINew.getWidth()); 1909*cdf0e10cSrcweir const double fDPIYChange((double)aDPIOld.getHeight() / (double)aDPINew.getHeight()); 1910*cdf0e10cSrcweir 1911*cdf0e10cSrcweir if(!basegfx::fTools::equal(fDPIXChange, 1.0) || !basegfx::fTools::equal(fDPIYChange, 1.0)) 1912*cdf0e10cSrcweir { 1913*cdf0e10cSrcweir aViewTransform.scale(fDPIXChange, fDPIYChange); 1914*cdf0e10cSrcweir } 1915*cdf0e10cSrcweir 1916*cdf0e10cSrcweir // create view information and pixel renderer. Reuse known ViewInformation 1917*cdf0e10cSrcweir // except new transformation and range 1918*cdf0e10cSrcweir const geometry::ViewInformation2D aViewInfo( 1919*cdf0e10cSrcweir getViewInformation2D().getObjectTransformation(), 1920*cdf0e10cSrcweir aViewTransform, 1921*cdf0e10cSrcweir aViewRange, 1922*cdf0e10cSrcweir getViewInformation2D().getVisualizedPage(), 1923*cdf0e10cSrcweir getViewInformation2D().getViewTime(), 1924*cdf0e10cSrcweir getViewInformation2D().getExtendedInformationSequence()); 1925*cdf0e10cSrcweir 1926*cdf0e10cSrcweir VclPixelProcessor2D aBufferProcessor(aViewInfo, aBufferDevice); 1927*cdf0e10cSrcweir 1928*cdf0e10cSrcweir // draw content using pixel renderer 1929*cdf0e10cSrcweir aBufferProcessor.process(rContent); 1930*cdf0e10cSrcweir const Bitmap aBmContent(aBufferDevice.GetBitmap(aEmptyPoint, aSizePixel)); 1931*cdf0e10cSrcweir 1932*cdf0e10cSrcweir // draw transparence using pixel renderer 1933*cdf0e10cSrcweir aBufferDevice.Erase(); 1934*cdf0e10cSrcweir aBufferProcessor.process(rTransparence); 1935*cdf0e10cSrcweir const AlphaMask aBmAlpha(aBufferDevice.GetBitmap(aEmptyPoint, aSizePixel)); 1936*cdf0e10cSrcweir 1937*cdf0e10cSrcweir #ifdef DBG_UTIL 1938*cdf0e10cSrcweir static bool bDoSaveForVisualControl(false); 1939*cdf0e10cSrcweir if(bDoSaveForVisualControl) 1940*cdf0e10cSrcweir { 1941*cdf0e10cSrcweir SvFileStream aNew(String(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); 1942*cdf0e10cSrcweir aNew << aBmContent; 1943*cdf0e10cSrcweir } 1944*cdf0e10cSrcweir #endif 1945*cdf0e10cSrcweir 1946*cdf0e10cSrcweir // paint 1947*cdf0e10cSrcweir mpOutputDevice->DrawBitmapEx( 1948*cdf0e10cSrcweir aRectLogic.TopLeft(), 1949*cdf0e10cSrcweir aRectLogic.GetSize(), 1950*cdf0e10cSrcweir BitmapEx(aBmContent, aBmAlpha)); 1951*cdf0e10cSrcweir } 1952*cdf0e10cSrcweir } 1953*cdf0e10cSrcweir } 1954*cdf0e10cSrcweir 1955*cdf0e10cSrcweir break; 1956*cdf0e10cSrcweir } 1957*cdf0e10cSrcweir case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D : 1958*cdf0e10cSrcweir { 1959*cdf0e10cSrcweir // use default transform group pocessing 1960*cdf0e10cSrcweir RenderTransformPrimitive2D(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate)); 1961*cdf0e10cSrcweir break; 1962*cdf0e10cSrcweir } 1963*cdf0e10cSrcweir case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D : 1964*cdf0e10cSrcweir { 1965*cdf0e10cSrcweir // new XDrawPage for ViewInformation2D 1966*cdf0e10cSrcweir RenderPagePreviewPrimitive2D(static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate)); 1967*cdf0e10cSrcweir break; 1968*cdf0e10cSrcweir } 1969*cdf0e10cSrcweir case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D : 1970*cdf0e10cSrcweir { 1971*cdf0e10cSrcweir // use default marker array pocessing 1972*cdf0e10cSrcweir RenderMarkerArrayPrimitive2D(static_cast< const primitive2d::MarkerArrayPrimitive2D& >(rCandidate)); 1973*cdf0e10cSrcweir break; 1974*cdf0e10cSrcweir } 1975*cdf0e10cSrcweir case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D : 1976*cdf0e10cSrcweir { 1977*cdf0e10cSrcweir // use default point array pocessing 1978*cdf0e10cSrcweir RenderPointArrayPrimitive2D(static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate)); 1979*cdf0e10cSrcweir break; 1980*cdf0e10cSrcweir } 1981*cdf0e10cSrcweir case PRIMITIVE2D_ID_CHARTPRIMITIVE2D : 1982*cdf0e10cSrcweir { 1983*cdf0e10cSrcweir // ChartPrimitive2D 1984*cdf0e10cSrcweir const primitive2d::ChartPrimitive2D& rChartPrimitive = static_cast< const primitive2d::ChartPrimitive2D& >(rCandidate); 1985*cdf0e10cSrcweir 1986*cdf0e10cSrcweir if(!renderChartPrimitive2D( 1987*cdf0e10cSrcweir rChartPrimitive, 1988*cdf0e10cSrcweir *mpOutputDevice, 1989*cdf0e10cSrcweir getViewInformation2D())) 1990*cdf0e10cSrcweir { 1991*cdf0e10cSrcweir // fallback to decomposition (MetaFile) 1992*cdf0e10cSrcweir process(rChartPrimitive.get2DDecomposition(getViewInformation2D())); 1993*cdf0e10cSrcweir } 1994*cdf0e10cSrcweir break; 1995*cdf0e10cSrcweir } 1996*cdf0e10cSrcweir case PRIMITIVE2D_ID_STRUCTURETAGPRIMITIVE2D : 1997*cdf0e10cSrcweir { 1998*cdf0e10cSrcweir // structured tag primitive 1999*cdf0e10cSrcweir const primitive2d::StructureTagPrimitive2D& rStructureTagCandidate = static_cast< const primitive2d::StructureTagPrimitive2D& >(rCandidate); 2000*cdf0e10cSrcweir const vcl::PDFWriter::StructElement& rTagElement(rStructureTagCandidate.getStructureElement()); 2001*cdf0e10cSrcweir const bool bTagUsed(vcl::PDFWriter::NonStructElement != rTagElement); 2002*cdf0e10cSrcweir 2003*cdf0e10cSrcweir if(mpPDFExtOutDevData && bTagUsed) 2004*cdf0e10cSrcweir { 2005*cdf0e10cSrcweir // write start tag 2006*cdf0e10cSrcweir mpPDFExtOutDevData->BeginStructureElement(rTagElement); 2007*cdf0e10cSrcweir } 2008*cdf0e10cSrcweir 2009*cdf0e10cSrcweir // proccess childs normally 2010*cdf0e10cSrcweir process(rStructureTagCandidate.getChildren()); 2011*cdf0e10cSrcweir 2012*cdf0e10cSrcweir if(mpPDFExtOutDevData && bTagUsed) 2013*cdf0e10cSrcweir { 2014*cdf0e10cSrcweir // write end tag 2015*cdf0e10cSrcweir mpPDFExtOutDevData->EndStructureElement(); 2016*cdf0e10cSrcweir } 2017*cdf0e10cSrcweir 2018*cdf0e10cSrcweir break; 2019*cdf0e10cSrcweir } 2020*cdf0e10cSrcweir case PRIMITIVE2D_ID_EPSPRIMITIVE2D : 2021*cdf0e10cSrcweir { 2022*cdf0e10cSrcweir RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); 2023*cdf0e10cSrcweir break; 2024*cdf0e10cSrcweir } 2025*cdf0e10cSrcweir default : 2026*cdf0e10cSrcweir { 2027*cdf0e10cSrcweir // process recursively 2028*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 2029*cdf0e10cSrcweir break; 2030*cdf0e10cSrcweir } 2031*cdf0e10cSrcweir } 2032*cdf0e10cSrcweir } 2033*cdf0e10cSrcweir } // end of namespace processor2d 2034*cdf0e10cSrcweir } // end of namespace drawinglayer 2035*cdf0e10cSrcweir 2036*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 2037*cdf0e10cSrcweir // eof 2038