1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <drawinglayer/processor2d/vclpixelprocessor2d.hxx> 32*cdf0e10cSrcweir #include <vcl/outdev.hxx> 33*cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 34*cdf0e10cSrcweir #include <drawinglayer/primitive2d/textprimitive2d.hxx> 35*cdf0e10cSrcweir #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 36*cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 37*cdf0e10cSrcweir #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 38*cdf0e10cSrcweir #include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx> 39*cdf0e10cSrcweir #include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx> 40*cdf0e10cSrcweir #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> 41*cdf0e10cSrcweir #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 42*cdf0e10cSrcweir #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> 43*cdf0e10cSrcweir #include <drawinglayer/primitive2d/transparenceprimitive2d.hxx> 44*cdf0e10cSrcweir #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 45*cdf0e10cSrcweir #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> 46*cdf0e10cSrcweir #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx> 47*cdf0e10cSrcweir #include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx> 48*cdf0e10cSrcweir #include <drawinglayer/primitive2d/controlprimitive2d.hxx> 49*cdf0e10cSrcweir #include <com/sun/star/awt/XWindow2.hpp> 50*cdf0e10cSrcweir #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 51*cdf0e10cSrcweir #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> 52*cdf0e10cSrcweir #include <drawinglayer/primitive2d/chartprimitive2d.hxx> 53*cdf0e10cSrcweir #include <helperchartrenderer.hxx> 54*cdf0e10cSrcweir #include <helperwrongspellrenderer.hxx> 55*cdf0e10cSrcweir #include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx> 56*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 57*cdf0e10cSrcweir #include <vcl/hatch.hxx> 58*cdf0e10cSrcweir #include <tools/diagnose_ex.h> 59*cdf0e10cSrcweir #include <com/sun/star/awt/PosSize.hpp> 60*cdf0e10cSrcweir #include <drawinglayer/primitive2d/invertprimitive2d.hxx> 61*cdf0e10cSrcweir #include <cstdio> 62*cdf0e10cSrcweir #include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> 63*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx> 64*cdf0e10cSrcweir #include <drawinglayer/primitive2d/epsprimitive2d.hxx> 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx> 67*cdf0e10cSrcweir #include <vcl/window.hxx> 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir using namespace com::sun::star; 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir namespace drawinglayer 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir namespace processor2d 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir VclPixelProcessor2D::VclPixelProcessor2D(const geometry::ViewInformation2D& rViewInformation, OutputDevice& rOutDev) 80*cdf0e10cSrcweir : VclProcessor2D(rViewInformation, rOutDev), 81*cdf0e10cSrcweir maOriginalMapMode(rOutDev.GetMapMode()) 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir // prepare maCurrentTransformation matrix with viewTransformation to target directly to pixels 84*cdf0e10cSrcweir maCurrentTransformation = rViewInformation.getObjectToViewTransformation(); 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir // prepare output directly to pixels 87*cdf0e10cSrcweir mpOutputDevice->Push(PUSH_MAPMODE); 88*cdf0e10cSrcweir mpOutputDevice->SetMapMode(); 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir // react on AntiAliasing settings 91*cdf0e10cSrcweir if(getOptionsDrawinglayer().IsAntiAliasing()) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW); 94*cdf0e10cSrcweir } 95*cdf0e10cSrcweir else 96*cdf0e10cSrcweir { 97*cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir VclPixelProcessor2D::~VclPixelProcessor2D() 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir // restore MapMode 104*cdf0e10cSrcweir mpOutputDevice->Pop(); 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir // restore AntiAliasing 107*cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 108*cdf0e10cSrcweir } 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir switch(rCandidate.getPrimitive2DID()) 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir // directdraw of wrong spell primitive; added test possibility to check wrong spell decompose 117*cdf0e10cSrcweir static bool bHandleWrongSpellDirectly(true); 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir if(bHandleWrongSpellDirectly) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive = static_cast< const primitive2d::WrongSpellPrimitive2D& >(rCandidate); 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir if(!renderWrongSpellPrimitive2D( 124*cdf0e10cSrcweir rWrongSpellPrimitive, 125*cdf0e10cSrcweir *mpOutputDevice, 126*cdf0e10cSrcweir maCurrentTransformation, 127*cdf0e10cSrcweir maBColorModifierStack)) 128*cdf0e10cSrcweir { 129*cdf0e10cSrcweir // fallback to decomposition (MetaFile) 130*cdf0e10cSrcweir process(rWrongSpellPrimitive.get2DDecomposition(getViewInformation2D())); 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir } 133*cdf0e10cSrcweir else 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir break; 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D : 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir // directdraw of text simple portion; added test possibility to check text decompose 142*cdf0e10cSrcweir static bool bForceSimpleTextDecomposition(false); 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir // Adapt evtl. used special DrawMode 145*cdf0e10cSrcweir const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 146*cdf0e10cSrcweir adaptTextToFillDrawMode(); 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect()) 149*cdf0e10cSrcweir { 150*cdf0e10cSrcweir RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir else 153*cdf0e10cSrcweir { 154*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir // restore DrawMode 158*cdf0e10cSrcweir mpOutputDevice->SetDrawMode(nOriginalDrawMode); 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir break; 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D : 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir // directdraw of text simple portion; added test possibility to check text decompose 165*cdf0e10cSrcweir static bool bForceComplexTextDecomposition(false); 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir // Adapt evtl. used special DrawMode 168*cdf0e10cSrcweir const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 169*cdf0e10cSrcweir adaptTextToFillDrawMode(); 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect()) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir else 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 178*cdf0e10cSrcweir } 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir // restore DrawMode 181*cdf0e10cSrcweir mpOutputDevice->SetDrawMode(nOriginalDrawMode); 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir break; 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir // direct draw of hairline 188*cdf0e10cSrcweir RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), true); 189*cdf0e10cSrcweir break; 190*cdf0e10cSrcweir } 191*cdf0e10cSrcweir case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D : 192*cdf0e10cSrcweir { 193*cdf0e10cSrcweir // direct draw of transformed BitmapEx primitive 194*cdf0e10cSrcweir RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate)); 195*cdf0e10cSrcweir break; 196*cdf0e10cSrcweir } 197*cdf0e10cSrcweir case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D : 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir // direct draw of transformed BitmapEx primitive 200*cdf0e10cSrcweir RenderRenderGraphicPrimitive2D(static_cast< const primitive2d::RenderGraphicPrimitive2D& >(rCandidate)); 201*cdf0e10cSrcweir break; 202*cdf0e10cSrcweir } 203*cdf0e10cSrcweir case PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D : 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir // direct draw of fillBitmapPrimitive 206*cdf0e10cSrcweir RenderFillBitmapPrimitive2D(static_cast< const primitive2d::FillBitmapPrimitive2D& >(rCandidate)); 207*cdf0e10cSrcweir break; 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D : 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir // direct draw of gradient 212*cdf0e10cSrcweir RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate)); 213*cdf0e10cSrcweir break; 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D : 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir // direct draw of bitmap 218*cdf0e10cSrcweir RenderPolyPolygonBitmapPrimitive2D(static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate)); 219*cdf0e10cSrcweir break; 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D : 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir // direct draw of PolyPolygon with color 224*cdf0e10cSrcweir RenderPolyPolygonColorPrimitive2D(static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate)); 225*cdf0e10cSrcweir break; 226*cdf0e10cSrcweir } 227*cdf0e10cSrcweir case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D : 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir // #i98289# 230*cdf0e10cSrcweir const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()); 231*cdf0e10cSrcweir const sal_uInt16 nOldAntiAliase(mpOutputDevice->GetAntialiasing()); 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir if(bForceLineSnap) 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE); 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir static bool bTestMetaFilePrimitiveDecomposition(true); 239*cdf0e10cSrcweir if(bTestMetaFilePrimitiveDecomposition) 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir // use new Metafile decomposition 242*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 243*cdf0e10cSrcweir } 244*cdf0e10cSrcweir else 245*cdf0e10cSrcweir { 246*cdf0e10cSrcweir // direct draw of MetaFile 247*cdf0e10cSrcweir RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate)); 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir if(bForceLineSnap) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nOldAntiAliase); 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir break; 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir case PRIMITIVE2D_ID_MASKPRIMITIVE2D : 258*cdf0e10cSrcweir { 259*cdf0e10cSrcweir // mask group. 260*cdf0e10cSrcweir RenderMaskPrimitive2DPixel(static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate)); 261*cdf0e10cSrcweir break; 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D : 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir // modified color group. Force output to unified color. 266*cdf0e10cSrcweir RenderModifiedColorPrimitive2D(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate)); 267*cdf0e10cSrcweir break; 268*cdf0e10cSrcweir } 269*cdf0e10cSrcweir case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D : 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir // Detect if a single PolyPolygonColorPrimitive2D is contained; in that case, 272*cdf0e10cSrcweir // use the faster OutputDevice::DrawTransparent method 273*cdf0e10cSrcweir const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate); 274*cdf0e10cSrcweir const primitive2d::Primitive2DSequence rContent = rUniTransparenceCandidate.getChildren(); 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir if(rContent.hasElements()) 277*cdf0e10cSrcweir { 278*cdf0e10cSrcweir if(0.0 == rUniTransparenceCandidate.getTransparence()) 279*cdf0e10cSrcweir { 280*cdf0e10cSrcweir // not transparent at all, use content 281*cdf0e10cSrcweir process(rUniTransparenceCandidate.getChildren()); 282*cdf0e10cSrcweir } 283*cdf0e10cSrcweir else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0) 284*cdf0e10cSrcweir { 285*cdf0e10cSrcweir bool bDrawTransparentUsed(false); 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir // since DEV300 m33 DrawTransparent is supported in VCL (for some targets 288*cdf0e10cSrcweir // natively), so i am now enabling this shortcut 289*cdf0e10cSrcweir static bool bAllowUsingDrawTransparent(true); 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir if(bAllowUsingDrawTransparent && 1 == rContent.getLength()) 292*cdf0e10cSrcweir { 293*cdf0e10cSrcweir const primitive2d::Primitive2DReference xReference(rContent[0]); 294*cdf0e10cSrcweir const primitive2d::BasePrimitive2D* pBasePrimitive = dynamic_cast< const primitive2d::BasePrimitive2D* >(xReference.get()); 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir if(pBasePrimitive) 297*cdf0e10cSrcweir { 298*cdf0e10cSrcweir switch(pBasePrimitive->getPrimitive2DID()) 299*cdf0e10cSrcweir { 300*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D: 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir // single transparent PolyPolygon identified, use directly 303*cdf0e10cSrcweir const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive); 304*cdf0e10cSrcweir OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 305*cdf0e10cSrcweir const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); 306*cdf0e10cSrcweir mpOutputDevice->SetFillColor(Color(aPolygonColor)); 307*cdf0e10cSrcweir mpOutputDevice->SetLineColor(); 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir basegfx::B2DPolyPolygon aLocalPolyPolygon(pPoPoColor->getB2DPolyPolygon()); 310*cdf0e10cSrcweir aLocalPolyPolygon.transform(maCurrentTransformation); 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir mpOutputDevice->DrawTransparent(aLocalPolyPolygon, rUniTransparenceCandidate.getTransparence()); 313*cdf0e10cSrcweir bDrawTransparentUsed = true; 314*cdf0e10cSrcweir break; 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir // #i# need to wait for #i101378# which is in CWS vcl112 to directly paint transparent hairlines 317*cdf0e10cSrcweir //case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D: 318*cdf0e10cSrcweir //{ 319*cdf0e10cSrcweir // // single transparent PolygonHairlinePrimitive2D identified, use directly 320*cdf0e10cSrcweir // const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive); 321*cdf0e10cSrcweir // OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 322*cdf0e10cSrcweir // break; 323*cdf0e10cSrcweir //} 324*cdf0e10cSrcweir } 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir if(!bDrawTransparentUsed) 329*cdf0e10cSrcweir { 330*cdf0e10cSrcweir // unified sub-transparence. Draw to VDev first. 331*cdf0e10cSrcweir RenderUnifiedTransparencePrimitive2D(rUniTransparenceCandidate); 332*cdf0e10cSrcweir } 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir break; 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D : 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir // sub-transparence group. Draw to VDev first. 341*cdf0e10cSrcweir RenderTransparencePrimitive2D(static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate)); 342*cdf0e10cSrcweir break; 343*cdf0e10cSrcweir } 344*cdf0e10cSrcweir case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D : 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir // transform group. 347*cdf0e10cSrcweir RenderTransformPrimitive2D(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate)); 348*cdf0e10cSrcweir break; 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D : 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir // new XDrawPage for ViewInformation2D 353*cdf0e10cSrcweir RenderPagePreviewPrimitive2D(static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate)); 354*cdf0e10cSrcweir break; 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D : 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir // marker array 359*cdf0e10cSrcweir RenderMarkerArrayPrimitive2D(static_cast< const primitive2d::MarkerArrayPrimitive2D& >(rCandidate)); 360*cdf0e10cSrcweir break; 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D : 363*cdf0e10cSrcweir { 364*cdf0e10cSrcweir // point array 365*cdf0e10cSrcweir RenderPointArrayPrimitive2D(static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate)); 366*cdf0e10cSrcweir break; 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D : 369*cdf0e10cSrcweir { 370*cdf0e10cSrcweir // control primitive 371*cdf0e10cSrcweir const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate); 372*cdf0e10cSrcweir const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl()); 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir try 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir // remember old graphics and create new 377*cdf0e10cSrcweir uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW); 378*cdf0e10cSrcweir const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics()); 379*cdf0e10cSrcweir const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics()); 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir if(xNewGraphics.is()) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir // link graphics and view 384*cdf0e10cSrcweir xControlView->setGraphics(xNewGraphics); 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir // get position 387*cdf0e10cSrcweir const basegfx::B2DHomMatrix aObjectToPixel(maCurrentTransformation * rControlPrimitive.getTransform()); 388*cdf0e10cSrcweir const basegfx::B2DPoint aTopLeftPixel(aObjectToPixel * basegfx::B2DPoint(0.0, 0.0)); 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir // find out if the control is already visualized as a VCL-ChildWindow. If yes, 391*cdf0e10cSrcweir // it does not need to be painted at all. 392*cdf0e10cSrcweir uno::Reference< awt::XWindow2 > xControlWindow(rXControl, uno::UNO_QUERY_THROW); 393*cdf0e10cSrcweir const bool bControlIsVisibleAsChildWindow(rXControl->getPeer().is() && xControlWindow->isVisible()); 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir if(!bControlIsVisibleAsChildWindow) 396*cdf0e10cSrcweir { 397*cdf0e10cSrcweir // draw it. Do not forget to use the evtl. offsetted origin of the target device, 398*cdf0e10cSrcweir // e.g. when used with mask/transparence buffer device 399*cdf0e10cSrcweir const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin()); 400*cdf0e10cSrcweir xControlView->draw( 401*cdf0e10cSrcweir aOrigin.X() + basegfx::fround(aTopLeftPixel.getX()), 402*cdf0e10cSrcweir aOrigin.Y() + basegfx::fround(aTopLeftPixel.getY())); 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir // restore original graphics 406*cdf0e10cSrcweir xControlView->setGraphics(xOriginalGraphics); 407*cdf0e10cSrcweir } 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir catch(const uno::Exception&) 410*cdf0e10cSrcweir { 411*cdf0e10cSrcweir // #i116763# removing since there is a good alternative when the xControlView 412*cdf0e10cSrcweir // is not found and it is allowed to happen 413*cdf0e10cSrcweir // DBG_UNHANDLED_EXCEPTION(); 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir // process recursively and use the decomposition as Bitmap 416*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir 419*cdf0e10cSrcweir break; 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D: 422*cdf0e10cSrcweir { 423*cdf0e10cSrcweir // the stroke primitive may be decomposed to filled polygons. To keep 424*cdf0e10cSrcweir // evtl. set DrawModes aka DRAWMODE_BLACKLINE, DRAWMODE_GRAYLINE, 425*cdf0e10cSrcweir // DRAWMODE_GHOSTEDLINE, DRAWMODE_WHITELINE or DRAWMODE_SETTINGSLINE 426*cdf0e10cSrcweir // working, these need to be copied to the corresponding fill modes 427*cdf0e10cSrcweir const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 428*cdf0e10cSrcweir adaptLineToFillDrawMode(); 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir // polygon stroke primitive 431*cdf0e10cSrcweir static bool bSuppressFatToHairlineCorrection(false); 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir if(bSuppressFatToHairlineCorrection) 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir // remeber that we enter a PolygonStrokePrimitive2D decomposition, 436*cdf0e10cSrcweir // used for AA thick line drawing 437*cdf0e10cSrcweir mnPolygonStrokePrimitive2D++; 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir // with AA there is no need to handle thin lines special 440*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir // leave PolygonStrokePrimitive2D 443*cdf0e10cSrcweir mnPolygonStrokePrimitive2D--; 444*cdf0e10cSrcweir } 445*cdf0e10cSrcweir else 446*cdf0e10cSrcweir { 447*cdf0e10cSrcweir // Lines with 1 and 2 pixel width without AA need special treatment since their vsiualisation 448*cdf0e10cSrcweir // as filled polygons is geometrically corret but looks wrong since polygon filling avoids 449*cdf0e10cSrcweir // the right and bottom pixels. The used method evaluates that and takes the correct action, 450*cdf0e10cSrcweir // including calling recursively with decomposition if line is wide enough 451*cdf0e10cSrcweir const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate); 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive); 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir // restore DrawMode 457*cdf0e10cSrcweir mpOutputDevice->SetDrawMode(nOriginalDrawMode); 458*cdf0e10cSrcweir 459*cdf0e10cSrcweir break; 460*cdf0e10cSrcweir } 461*cdf0e10cSrcweir case PRIMITIVE2D_ID_CHARTPRIMITIVE2D : 462*cdf0e10cSrcweir { 463*cdf0e10cSrcweir // chart primitive in pixel renderer; restore original DrawMode during call 464*cdf0e10cSrcweir // since the evtl. used ChartPrettyPainter will use the MapMode 465*cdf0e10cSrcweir const primitive2d::ChartPrimitive2D& rChartPrimitive = static_cast< const primitive2d::ChartPrimitive2D& >(rCandidate); 466*cdf0e10cSrcweir mpOutputDevice->Push(PUSH_MAPMODE); 467*cdf0e10cSrcweir mpOutputDevice->SetMapMode(maOriginalMapMode); 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir if(!renderChartPrimitive2D( 470*cdf0e10cSrcweir rChartPrimitive, 471*cdf0e10cSrcweir *mpOutputDevice, 472*cdf0e10cSrcweir getViewInformation2D())) 473*cdf0e10cSrcweir { 474*cdf0e10cSrcweir // fallback to decomposition (MetaFile) 475*cdf0e10cSrcweir process(rChartPrimitive.get2DDecomposition(getViewInformation2D())); 476*cdf0e10cSrcweir } 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir mpOutputDevice->Pop(); 479*cdf0e10cSrcweir break; 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir case PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D : 482*cdf0e10cSrcweir { 483*cdf0e10cSrcweir static bool bForceIgnoreHatchSmoothing(false); 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir if(bForceIgnoreHatchSmoothing || getOptionsDrawinglayer().IsAntiAliasing()) 486*cdf0e10cSrcweir { 487*cdf0e10cSrcweir // if AA is used (or ignore smoothing is on), there is no need to smooth 488*cdf0e10cSrcweir // hatch painting, use decomposition 489*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 490*cdf0e10cSrcweir } 491*cdf0e10cSrcweir else 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir // without AA, use VCL to draw the hatch. It snaps hatch distances to the next pixel 494*cdf0e10cSrcweir // and forces hatch distance to be >= 3 pixels to make the hatch display look smoother. 495*cdf0e10cSrcweir // This is wrong in principle, but looks nicer. This could also be done here directly 496*cdf0e10cSrcweir // without VCL usage if needed 497*cdf0e10cSrcweir const primitive2d::FillHatchPrimitive2D& rFillHatchPrimitive = static_cast< const primitive2d::FillHatchPrimitive2D& >(rCandidate); 498*cdf0e10cSrcweir const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch(); 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir // create hatch polygon in range size and discrete coordinates 501*cdf0e10cSrcweir basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getObjectRange()); 502*cdf0e10cSrcweir aHatchRange.transform(maCurrentTransformation); 503*cdf0e10cSrcweir const basegfx::B2DPolygon aHatchPolygon(basegfx::tools::createPolygonFromRect(aHatchRange)); 504*cdf0e10cSrcweir 505*cdf0e10cSrcweir if(rFillHatchAttributes.isFillBackground()) 506*cdf0e10cSrcweir { 507*cdf0e10cSrcweir // #i111846# background fill is active; draw fill polygon 508*cdf0e10cSrcweir const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor())); 509*cdf0e10cSrcweir 510*cdf0e10cSrcweir mpOutputDevice->SetFillColor(Color(aPolygonColor)); 511*cdf0e10cSrcweir mpOutputDevice->SetLineColor(); 512*cdf0e10cSrcweir mpOutputDevice->DrawPolygon(aHatchPolygon); 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir 515*cdf0e10cSrcweir // set hatch line color 516*cdf0e10cSrcweir const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor())); 517*cdf0e10cSrcweir mpOutputDevice->SetFillColor(); 518*cdf0e10cSrcweir mpOutputDevice->SetLineColor(Color(aHatchColor)); 519*cdf0e10cSrcweir 520*cdf0e10cSrcweir // get hatch style 521*cdf0e10cSrcweir HatchStyle eHatchStyle(HATCH_SINGLE); 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir switch(rFillHatchAttributes.getStyle()) 524*cdf0e10cSrcweir { 525*cdf0e10cSrcweir default : // HATCHSTYLE_SINGLE 526*cdf0e10cSrcweir { 527*cdf0e10cSrcweir break; 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir case attribute::HATCHSTYLE_DOUBLE : 530*cdf0e10cSrcweir { 531*cdf0e10cSrcweir eHatchStyle = HATCH_DOUBLE; 532*cdf0e10cSrcweir break; 533*cdf0e10cSrcweir } 534*cdf0e10cSrcweir case attribute::HATCHSTYLE_TRIPLE : 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir eHatchStyle = HATCH_TRIPLE; 537*cdf0e10cSrcweir break; 538*cdf0e10cSrcweir } 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir // create hatch 542*cdf0e10cSrcweir const basegfx::B2DVector aDiscreteDistance(maCurrentTransformation * basegfx::B2DVector(rFillHatchAttributes.getDistance(), 0.0)); 543*cdf0e10cSrcweir const sal_uInt32 nDistance(basegfx::fround(aDiscreteDistance.getLength())); 544*cdf0e10cSrcweir const sal_uInt16 nAngle10((sal_uInt16)basegfx::fround(rFillHatchAttributes.getAngle() / F_PI1800)); 545*cdf0e10cSrcweir ::Hatch aVCLHatch(eHatchStyle, Color(rFillHatchAttributes.getColor()), nDistance, nAngle10); 546*cdf0e10cSrcweir 547*cdf0e10cSrcweir // draw hatch using VCL 548*cdf0e10cSrcweir mpOutputDevice->DrawHatch(PolyPolygon(Polygon(aHatchPolygon)), aVCLHatch); 549*cdf0e10cSrcweir } 550*cdf0e10cSrcweir break; 551*cdf0e10cSrcweir } 552*cdf0e10cSrcweir case PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D : 553*cdf0e10cSrcweir { 554*cdf0e10cSrcweir // #i98404# Handle directly, especially when AA is active 555*cdf0e10cSrcweir const primitive2d::BackgroundColorPrimitive2D& rPrimitive = static_cast< const primitive2d::BackgroundColorPrimitive2D& >(rCandidate); 556*cdf0e10cSrcweir const sal_uInt16 nOriginalAA(mpOutputDevice->GetAntialiasing()); 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir // switch AA off in all cases 559*cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir // create color for fill 562*cdf0e10cSrcweir const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor())); 563*cdf0e10cSrcweir mpOutputDevice->SetFillColor(Color(aPolygonColor)); 564*cdf0e10cSrcweir mpOutputDevice->SetLineColor(); 565*cdf0e10cSrcweir 566*cdf0e10cSrcweir // create rectangle for fill 567*cdf0e10cSrcweir const basegfx::B2DRange& aViewport(getViewInformation2D().getDiscreteViewport()); 568*cdf0e10cSrcweir const Rectangle aRectangle( 569*cdf0e10cSrcweir (sal_Int32)floor(aViewport.getMinX()), (sal_Int32)floor(aViewport.getMinY()), 570*cdf0e10cSrcweir (sal_Int32)ceil(aViewport.getMaxX()), (sal_Int32)ceil(aViewport.getMaxY())); 571*cdf0e10cSrcweir mpOutputDevice->DrawRect(aRectangle); 572*cdf0e10cSrcweir 573*cdf0e10cSrcweir // restore AA setting 574*cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nOriginalAA); 575*cdf0e10cSrcweir break; 576*cdf0e10cSrcweir } 577*cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D : 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir // #i97628# 580*cdf0e10cSrcweir // This primitive means that the content is derived from an active text edit, 581*cdf0e10cSrcweir // not from model data itself. Some renderers need to suppress this content, e.g. 582*cdf0e10cSrcweir // the pixel renderer used for displaying the edit view (like this one). It's 583*cdf0e10cSrcweir // not to be suppressed by the MetaFile renderers, so that the edited text is 584*cdf0e10cSrcweir // part of the MetaFile, e.g. needed for presentation previews. 585*cdf0e10cSrcweir // Action: Ignore here, do nothing. 586*cdf0e10cSrcweir break; 587*cdf0e10cSrcweir } 588*cdf0e10cSrcweir case PRIMITIVE2D_ID_INVERTPRIMITIVE2D : 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir // invert primitive (currently only used for HighContrast fallback for selection in SW and SC). 591*cdf0e10cSrcweir // Set OutDev to XOR and switch AA off (XOR does not work with AA) 592*cdf0e10cSrcweir mpOutputDevice->Push(); 593*cdf0e10cSrcweir mpOutputDevice->SetRasterOp( ROP_XOR ); 594*cdf0e10cSrcweir const sal_uInt16 nAntiAliasing(mpOutputDevice->GetAntialiasing()); 595*cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nAntiAliasing & ~ANTIALIASING_ENABLE_B2DDRAW); 596*cdf0e10cSrcweir 597*cdf0e10cSrcweir // process content recursively 598*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir // restore OutDev 601*cdf0e10cSrcweir mpOutputDevice->Pop(); 602*cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nAntiAliasing); 603*cdf0e10cSrcweir break; 604*cdf0e10cSrcweir } 605*cdf0e10cSrcweir case PRIMITIVE2D_ID_EPSPRIMITIVE2D : 606*cdf0e10cSrcweir { 607*cdf0e10cSrcweir RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); 608*cdf0e10cSrcweir break; 609*cdf0e10cSrcweir } 610*cdf0e10cSrcweir default : 611*cdf0e10cSrcweir { 612*cdf0e10cSrcweir // process recursively 613*cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 614*cdf0e10cSrcweir break; 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir } 618*cdf0e10cSrcweir } // end of namespace processor2d 619*cdf0e10cSrcweir } // end of namespace drawinglayer 620*cdf0e10cSrcweir 621*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 622*cdf0e10cSrcweir // eof 623