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