1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove 25*b1cdbd2cSJim Jagielski #include "precompiled_drawinglayer.hxx" 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include <drawinglayer/processor2d/vclpixelprocessor2d.hxx> 28*b1cdbd2cSJim Jagielski #include <vcl/outdev.hxx> 29*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 30*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/textprimitive2d.hxx> 31*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 32*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 33*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 34*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx> 35*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> 36*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 37*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> 38*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/transparenceprimitive2d.hxx> 39*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 40*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> 41*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx> 42*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx> 43*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/controlprimitive2d.hxx> 44*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/XWindow2.hpp> 45*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 46*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> 47*b1cdbd2cSJim Jagielski #include <helperwrongspellrenderer.hxx> 48*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx> 49*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygontools.hxx> 50*b1cdbd2cSJim Jagielski #include <vcl/hatch.hxx> 51*b1cdbd2cSJim Jagielski #include <tools/diagnose_ex.h> 52*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/PosSize.hpp> 53*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/invertprimitive2d.hxx> 54*b1cdbd2cSJim Jagielski #include <cstdio> 55*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> 56*b1cdbd2cSJim Jagielski #include <basegfx/matrix/b2dhommatrixtools.hxx> 57*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/epsprimitive2d.hxx> 58*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/svggradientprimitive2d.hxx> 59*b1cdbd2cSJim Jagielski #include <toolkit/helper/vclunohelper.hxx> 60*b1cdbd2cSJim Jagielski #include <vcl/window.hxx> 61*b1cdbd2cSJim Jagielski 62*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 63*b1cdbd2cSJim Jagielski 64*b1cdbd2cSJim Jagielski using namespace com::sun::star; 65*b1cdbd2cSJim Jagielski 66*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 67*b1cdbd2cSJim Jagielski 68*b1cdbd2cSJim Jagielski namespace drawinglayer 69*b1cdbd2cSJim Jagielski { 70*b1cdbd2cSJim Jagielski namespace processor2d 71*b1cdbd2cSJim Jagielski { VclPixelProcessor2D(const geometry::ViewInformation2D & rViewInformation,OutputDevice & rOutDev)72*b1cdbd2cSJim Jagielski VclPixelProcessor2D::VclPixelProcessor2D(const geometry::ViewInformation2D& rViewInformation, OutputDevice& rOutDev) 73*b1cdbd2cSJim Jagielski : VclProcessor2D(rViewInformation, rOutDev) 74*b1cdbd2cSJim Jagielski { 75*b1cdbd2cSJim Jagielski // prepare maCurrentTransformation matrix with viewTransformation to target directly to pixels 76*b1cdbd2cSJim Jagielski maCurrentTransformation = rViewInformation.getObjectToViewTransformation(); 77*b1cdbd2cSJim Jagielski 78*b1cdbd2cSJim Jagielski // prepare output directly to pixels 79*b1cdbd2cSJim Jagielski mpOutputDevice->Push(PUSH_MAPMODE); 80*b1cdbd2cSJim Jagielski mpOutputDevice->SetMapMode(); 81*b1cdbd2cSJim Jagielski 82*b1cdbd2cSJim Jagielski // react on AntiAliasing settings 83*b1cdbd2cSJim Jagielski if(getOptionsDrawinglayer().IsAntiAliasing()) 84*b1cdbd2cSJim Jagielski { 85*b1cdbd2cSJim Jagielski mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW); 86*b1cdbd2cSJim Jagielski } 87*b1cdbd2cSJim Jagielski else 88*b1cdbd2cSJim Jagielski { 89*b1cdbd2cSJim Jagielski mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 90*b1cdbd2cSJim Jagielski } 91*b1cdbd2cSJim Jagielski } 92*b1cdbd2cSJim Jagielski ~VclPixelProcessor2D()93*b1cdbd2cSJim Jagielski VclPixelProcessor2D::~VclPixelProcessor2D() 94*b1cdbd2cSJim Jagielski { 95*b1cdbd2cSJim Jagielski // restore MapMode 96*b1cdbd2cSJim Jagielski mpOutputDevice->Pop(); 97*b1cdbd2cSJim Jagielski 98*b1cdbd2cSJim Jagielski // restore AntiAliasing 99*b1cdbd2cSJim Jagielski mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 100*b1cdbd2cSJim Jagielski } 101*b1cdbd2cSJim Jagielski tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D & rSource,double fTransparency)102*b1cdbd2cSJim Jagielski bool VclPixelProcessor2D::tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D& rSource, double fTransparency) 103*b1cdbd2cSJim Jagielski { 104*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aLocalPolyPolygon(rSource.getB2DPolyPolygon()); 105*b1cdbd2cSJim Jagielski 106*b1cdbd2cSJim Jagielski if(!aLocalPolyPolygon.count()) 107*b1cdbd2cSJim Jagielski { 108*b1cdbd2cSJim Jagielski // no geometry, done 109*b1cdbd2cSJim Jagielski return true; 110*b1cdbd2cSJim Jagielski } 111*b1cdbd2cSJim Jagielski 112*b1cdbd2cSJim Jagielski const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rSource.getBColor())); 113*b1cdbd2cSJim Jagielski 114*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(aPolygonColor)); 115*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 116*b1cdbd2cSJim Jagielski aLocalPolyPolygon.transform(maCurrentTransformation); 117*b1cdbd2cSJim Jagielski mpOutputDevice->DrawTransparent( 118*b1cdbd2cSJim Jagielski aLocalPolyPolygon, 119*b1cdbd2cSJim Jagielski fTransparency); 120*b1cdbd2cSJim Jagielski 121*b1cdbd2cSJim Jagielski return true; 122*b1cdbd2cSJim Jagielski } 123*b1cdbd2cSJim Jagielski tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D & rSource,double fTransparency)124*b1cdbd2cSJim Jagielski bool VclPixelProcessor2D::tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D& rSource, double fTransparency) 125*b1cdbd2cSJim Jagielski { 126*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon()); 127*b1cdbd2cSJim Jagielski 128*b1cdbd2cSJim Jagielski if(!aLocalPolygon.count()) 129*b1cdbd2cSJim Jagielski { 130*b1cdbd2cSJim Jagielski // no geometry, done 131*b1cdbd2cSJim Jagielski return true; 132*b1cdbd2cSJim Jagielski } 133*b1cdbd2cSJim Jagielski 134*b1cdbd2cSJim Jagielski const basegfx::BColor aLineColor(maBColorModifierStack.getModifiedColor(rSource.getBColor())); 135*b1cdbd2cSJim Jagielski 136*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(); 137*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(Color(aLineColor)); 138*b1cdbd2cSJim Jagielski aLocalPolygon.transform(maCurrentTransformation); 139*b1cdbd2cSJim Jagielski 140*b1cdbd2cSJim Jagielski // try drawing; if it did not work, use standard fallback 141*b1cdbd2cSJim Jagielski if(mpOutputDevice->TryDrawPolyLineDirect( 142*b1cdbd2cSJim Jagielski aLocalPolygon, 143*b1cdbd2cSJim Jagielski 0.0, 144*b1cdbd2cSJim Jagielski fTransparency)) 145*b1cdbd2cSJim Jagielski { 146*b1cdbd2cSJim Jagielski return true; 147*b1cdbd2cSJim Jagielski } 148*b1cdbd2cSJim Jagielski 149*b1cdbd2cSJim Jagielski return false; 150*b1cdbd2cSJim Jagielski } 151*b1cdbd2cSJim Jagielski tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D & rSource,double fTransparency)152*b1cdbd2cSJim Jagielski bool VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D& rSource, double fTransparency) 153*b1cdbd2cSJim Jagielski { 154*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon()); 155*b1cdbd2cSJim Jagielski 156*b1cdbd2cSJim Jagielski if(!aLocalPolygon.count()) 157*b1cdbd2cSJim Jagielski { 158*b1cdbd2cSJim Jagielski // no geometry, done 159*b1cdbd2cSJim Jagielski return true; 160*b1cdbd2cSJim Jagielski } 161*b1cdbd2cSJim Jagielski 162*b1cdbd2cSJim Jagielski aLocalPolygon = basegfx::tools::simplifyCurveSegments(aLocalPolygon); 163*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aHairLinePolyPolygon; 164*b1cdbd2cSJim Jagielski 165*b1cdbd2cSJim Jagielski if(rSource.getStrokeAttribute().isDefault() || 0.0 == rSource.getStrokeAttribute().getFullDotDashLen()) 166*b1cdbd2cSJim Jagielski { 167*b1cdbd2cSJim Jagielski // no line dashing, just copy 168*b1cdbd2cSJim Jagielski aHairLinePolyPolygon.append(aLocalPolygon); 169*b1cdbd2cSJim Jagielski } 170*b1cdbd2cSJim Jagielski else 171*b1cdbd2cSJim Jagielski { 172*b1cdbd2cSJim Jagielski // apply LineStyle 173*b1cdbd2cSJim Jagielski basegfx::tools::applyLineDashing( 174*b1cdbd2cSJim Jagielski aLocalPolygon, 175*b1cdbd2cSJim Jagielski rSource.getStrokeAttribute().getDotDashArray(), 176*b1cdbd2cSJim Jagielski &aHairLinePolyPolygon, 177*b1cdbd2cSJim Jagielski 0, 178*b1cdbd2cSJim Jagielski rSource.getStrokeAttribute().getFullDotDashLen()); 179*b1cdbd2cSJim Jagielski } 180*b1cdbd2cSJim Jagielski 181*b1cdbd2cSJim Jagielski if(!aHairLinePolyPolygon.count()) 182*b1cdbd2cSJim Jagielski { 183*b1cdbd2cSJim Jagielski // no geometry, done 184*b1cdbd2cSJim Jagielski return true; 185*b1cdbd2cSJim Jagielski } 186*b1cdbd2cSJim Jagielski 187*b1cdbd2cSJim Jagielski const basegfx::BColor aLineColor( 188*b1cdbd2cSJim Jagielski maBColorModifierStack.getModifiedColor( 189*b1cdbd2cSJim Jagielski rSource.getLineAttribute().getColor())); 190*b1cdbd2cSJim Jagielski 191*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(); 192*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(Color(aLineColor)); 193*b1cdbd2cSJim Jagielski aHairLinePolyPolygon.transform(maCurrentTransformation); 194*b1cdbd2cSJim Jagielski 195*b1cdbd2cSJim Jagielski double fLineWidth(rSource.getLineAttribute().getWidth()); 196*b1cdbd2cSJim Jagielski 197*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(fLineWidth, 0.0)) 198*b1cdbd2cSJim Jagielski { 199*b1cdbd2cSJim Jagielski basegfx::B2DVector aLineWidth(fLineWidth, 0.0); 200*b1cdbd2cSJim Jagielski 201*b1cdbd2cSJim Jagielski aLineWidth = maCurrentTransformation * aLineWidth; 202*b1cdbd2cSJim Jagielski fLineWidth = aLineWidth.getLength(); 203*b1cdbd2cSJim Jagielski } 204*b1cdbd2cSJim Jagielski 205*b1cdbd2cSJim Jagielski bool bHasPoints(false); 206*b1cdbd2cSJim Jagielski bool bTryWorked(false); 207*b1cdbd2cSJim Jagielski 208*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++) 209*b1cdbd2cSJim Jagielski { 210*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon aSingle(aHairLinePolyPolygon.getB2DPolygon(a)); 211*b1cdbd2cSJim Jagielski 212*b1cdbd2cSJim Jagielski if(aSingle.count()) 213*b1cdbd2cSJim Jagielski { 214*b1cdbd2cSJim Jagielski bHasPoints = true; 215*b1cdbd2cSJim Jagielski 216*b1cdbd2cSJim Jagielski if(mpOutputDevice->TryDrawPolyLineDirect( 217*b1cdbd2cSJim Jagielski aSingle, 218*b1cdbd2cSJim Jagielski fLineWidth, 219*b1cdbd2cSJim Jagielski fTransparency, 220*b1cdbd2cSJim Jagielski rSource.getLineAttribute().getLineJoin(), 221*b1cdbd2cSJim Jagielski rSource.getLineAttribute().getLineCap())) 222*b1cdbd2cSJim Jagielski { 223*b1cdbd2cSJim Jagielski bTryWorked = true; 224*b1cdbd2cSJim Jagielski } 225*b1cdbd2cSJim Jagielski } 226*b1cdbd2cSJim Jagielski } 227*b1cdbd2cSJim Jagielski 228*b1cdbd2cSJim Jagielski if(!bTryWorked && !bHasPoints) 229*b1cdbd2cSJim Jagielski { 230*b1cdbd2cSJim Jagielski // no geometry despite try 231*b1cdbd2cSJim Jagielski bTryWorked = true; 232*b1cdbd2cSJim Jagielski } 233*b1cdbd2cSJim Jagielski 234*b1cdbd2cSJim Jagielski return bTryWorked; 235*b1cdbd2cSJim Jagielski } 236*b1cdbd2cSJim Jagielski processBasePrimitive2D(const primitive2d::BasePrimitive2D & rCandidate)237*b1cdbd2cSJim Jagielski void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) 238*b1cdbd2cSJim Jagielski { 239*b1cdbd2cSJim Jagielski switch(rCandidate.getPrimitive2DID()) 240*b1cdbd2cSJim Jagielski { 241*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : 242*b1cdbd2cSJim Jagielski { 243*b1cdbd2cSJim Jagielski // directdraw of wrong spell primitive; added test possibility to check wrong spell decompose 244*b1cdbd2cSJim Jagielski static bool bHandleWrongSpellDirectly(true); 245*b1cdbd2cSJim Jagielski 246*b1cdbd2cSJim Jagielski if(bHandleWrongSpellDirectly) 247*b1cdbd2cSJim Jagielski { 248*b1cdbd2cSJim Jagielski const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive = static_cast< const primitive2d::WrongSpellPrimitive2D& >(rCandidate); 249*b1cdbd2cSJim Jagielski 250*b1cdbd2cSJim Jagielski if(!renderWrongSpellPrimitive2D( 251*b1cdbd2cSJim Jagielski rWrongSpellPrimitive, 252*b1cdbd2cSJim Jagielski *mpOutputDevice, 253*b1cdbd2cSJim Jagielski maCurrentTransformation, 254*b1cdbd2cSJim Jagielski maBColorModifierStack)) 255*b1cdbd2cSJim Jagielski { 256*b1cdbd2cSJim Jagielski // fallback to decomposition (MetaFile) 257*b1cdbd2cSJim Jagielski process(rWrongSpellPrimitive.get2DDecomposition(getViewInformation2D())); 258*b1cdbd2cSJim Jagielski } 259*b1cdbd2cSJim Jagielski } 260*b1cdbd2cSJim Jagielski else 261*b1cdbd2cSJim Jagielski { 262*b1cdbd2cSJim Jagielski process(rCandidate.get2DDecomposition(getViewInformation2D())); 263*b1cdbd2cSJim Jagielski } 264*b1cdbd2cSJim Jagielski break; 265*b1cdbd2cSJim Jagielski } 266*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D : 267*b1cdbd2cSJim Jagielski { 268*b1cdbd2cSJim Jagielski // directdraw of text simple portion; added test possibility to check text decompose 269*b1cdbd2cSJim Jagielski static bool bForceSimpleTextDecomposition(false); 270*b1cdbd2cSJim Jagielski 271*b1cdbd2cSJim Jagielski // Adapt evtl. used special DrawMode 272*b1cdbd2cSJim Jagielski const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 273*b1cdbd2cSJim Jagielski adaptTextToFillDrawMode(); 274*b1cdbd2cSJim Jagielski 275*b1cdbd2cSJim Jagielski if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect()) 276*b1cdbd2cSJim Jagielski { 277*b1cdbd2cSJim Jagielski RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); 278*b1cdbd2cSJim Jagielski } 279*b1cdbd2cSJim Jagielski else 280*b1cdbd2cSJim Jagielski { 281*b1cdbd2cSJim Jagielski process(rCandidate.get2DDecomposition(getViewInformation2D())); 282*b1cdbd2cSJim Jagielski } 283*b1cdbd2cSJim Jagielski 284*b1cdbd2cSJim Jagielski // restore DrawMode 285*b1cdbd2cSJim Jagielski mpOutputDevice->SetDrawMode(nOriginalDrawMode); 286*b1cdbd2cSJim Jagielski 287*b1cdbd2cSJim Jagielski break; 288*b1cdbd2cSJim Jagielski } 289*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D : 290*b1cdbd2cSJim Jagielski { 291*b1cdbd2cSJim Jagielski // directdraw of text simple portion; added test possibility to check text decompose 292*b1cdbd2cSJim Jagielski static bool bForceComplexTextDecomposition(false); 293*b1cdbd2cSJim Jagielski 294*b1cdbd2cSJim Jagielski // Adapt evtl. used special DrawMode 295*b1cdbd2cSJim Jagielski const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 296*b1cdbd2cSJim Jagielski adaptTextToFillDrawMode(); 297*b1cdbd2cSJim Jagielski 298*b1cdbd2cSJim Jagielski if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect()) 299*b1cdbd2cSJim Jagielski { 300*b1cdbd2cSJim Jagielski RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); 301*b1cdbd2cSJim Jagielski } 302*b1cdbd2cSJim Jagielski else 303*b1cdbd2cSJim Jagielski { 304*b1cdbd2cSJim Jagielski process(rCandidate.get2DDecomposition(getViewInformation2D())); 305*b1cdbd2cSJim Jagielski } 306*b1cdbd2cSJim Jagielski 307*b1cdbd2cSJim Jagielski // restore DrawMode 308*b1cdbd2cSJim Jagielski mpOutputDevice->SetDrawMode(nOriginalDrawMode); 309*b1cdbd2cSJim Jagielski 310*b1cdbd2cSJim Jagielski break; 311*b1cdbd2cSJim Jagielski } 312*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : 313*b1cdbd2cSJim Jagielski { 314*b1cdbd2cSJim Jagielski // try to use directly 315*b1cdbd2cSJim Jagielski const primitive2d::PolygonHairlinePrimitive2D& rPolygonHairlinePrimitive2D = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate); 316*b1cdbd2cSJim Jagielski static bool bAllowed(true); 317*b1cdbd2cSJim Jagielski 318*b1cdbd2cSJim Jagielski if(bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(rPolygonHairlinePrimitive2D, 0.0)) 319*b1cdbd2cSJim Jagielski { 320*b1cdbd2cSJim Jagielski break; 321*b1cdbd2cSJim Jagielski } 322*b1cdbd2cSJim Jagielski 323*b1cdbd2cSJim Jagielski // direct draw of hairline 324*b1cdbd2cSJim Jagielski RenderPolygonHairlinePrimitive2D(rPolygonHairlinePrimitive2D, true); 325*b1cdbd2cSJim Jagielski break; 326*b1cdbd2cSJim Jagielski } 327*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D : 328*b1cdbd2cSJim Jagielski { 329*b1cdbd2cSJim Jagielski // direct draw of transformed BitmapEx primitive 330*b1cdbd2cSJim Jagielski const primitive2d::BitmapPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate); 331*b1cdbd2cSJim Jagielski 332*b1cdbd2cSJim Jagielski // check if graphic content is inside discrete local ViewPort 333*b1cdbd2cSJim Jagielski const basegfx::B2DRange& rDiscreteViewPort(getViewInformation2D().getDiscreteViewport()); 334*b1cdbd2cSJim Jagielski const basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rBitmapCandidate.getTransform()); 335*b1cdbd2cSJim Jagielski 336*b1cdbd2cSJim Jagielski if(!rDiscreteViewPort.isEmpty()) 337*b1cdbd2cSJim Jagielski { 338*b1cdbd2cSJim Jagielski basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0); 339*b1cdbd2cSJim Jagielski 340*b1cdbd2cSJim Jagielski aUnitRange.transform(aLocalTransform); 341*b1cdbd2cSJim Jagielski 342*b1cdbd2cSJim Jagielski if(!aUnitRange.overlaps(rDiscreteViewPort)) 343*b1cdbd2cSJim Jagielski { 344*b1cdbd2cSJim Jagielski // content is outside discrete local ViewPort 345*b1cdbd2cSJim Jagielski break; 346*b1cdbd2cSJim Jagielski } 347*b1cdbd2cSJim Jagielski } 348*b1cdbd2cSJim Jagielski 349*b1cdbd2cSJim Jagielski RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate)); 350*b1cdbd2cSJim Jagielski break; 351*b1cdbd2cSJim Jagielski } 352*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D : 353*b1cdbd2cSJim Jagielski { 354*b1cdbd2cSJim Jagielski // direct draw of fillBitmapPrimitive 355*b1cdbd2cSJim Jagielski RenderFillGraphicPrimitive2D(static_cast< const primitive2d::FillGraphicPrimitive2D& >(rCandidate)); 356*b1cdbd2cSJim Jagielski break; 357*b1cdbd2cSJim Jagielski } 358*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D : 359*b1cdbd2cSJim Jagielski { 360*b1cdbd2cSJim Jagielski // direct draw of gradient 361*b1cdbd2cSJim Jagielski const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate = static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate); 362*b1cdbd2cSJim Jagielski const attribute::FillGradientAttribute& rGradient(rPolygonCandidate.getFillGradient()); 363*b1cdbd2cSJim Jagielski basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor())); 364*b1cdbd2cSJim Jagielski basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor())); 365*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon()); 366*b1cdbd2cSJim Jagielski 367*b1cdbd2cSJim Jagielski if(aLocalPolyPolygon.count()) 368*b1cdbd2cSJim Jagielski { 369*b1cdbd2cSJim Jagielski aLocalPolyPolygon.transform(maCurrentTransformation); 370*b1cdbd2cSJim Jagielski 371*b1cdbd2cSJim Jagielski if(aStartColor == aEndColor) 372*b1cdbd2cSJim Jagielski { 373*b1cdbd2cSJim Jagielski // no gradient at all, draw as polygon in AA and non-AA case 374*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 375*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(aStartColor)); 376*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); 377*b1cdbd2cSJim Jagielski } 378*b1cdbd2cSJim Jagielski else 379*b1cdbd2cSJim Jagielski { 380*b1cdbd2cSJim Jagielski // use the primitive decomposition of the metafile 381*b1cdbd2cSJim Jagielski process(rPolygonCandidate.get2DDecomposition(getViewInformation2D())); 382*b1cdbd2cSJim Jagielski } 383*b1cdbd2cSJim Jagielski } 384*b1cdbd2cSJim Jagielski break; 385*b1cdbd2cSJim Jagielski } 386*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D : 387*b1cdbd2cSJim Jagielski { 388*b1cdbd2cSJim Jagielski // direct draw of bitmap 389*b1cdbd2cSJim Jagielski RenderPolyPolygonGraphicPrimitive2D(static_cast< const primitive2d::PolyPolygonGraphicPrimitive2D& >(rCandidate)); 390*b1cdbd2cSJim Jagielski break; 391*b1cdbd2cSJim Jagielski } 392*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D : 393*b1cdbd2cSJim Jagielski { 394*b1cdbd2cSJim Jagielski // try to use directly 395*b1cdbd2cSJim Jagielski const primitive2d::PolyPolygonColorPrimitive2D& rPolyPolygonColorPrimitive2D = static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate); 396*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aLocalPolyPolygon; 397*b1cdbd2cSJim Jagielski static bool bAllowed(true); 398*b1cdbd2cSJim Jagielski 399*b1cdbd2cSJim Jagielski if(bAllowed && tryDrawPolyPolygonColorPrimitive2DDirect(rPolyPolygonColorPrimitive2D, 0.0)) 400*b1cdbd2cSJim Jagielski { 401*b1cdbd2cSJim Jagielski // okay, done. In this case no gaps should have to be repaired, too 402*b1cdbd2cSJim Jagielski } 403*b1cdbd2cSJim Jagielski else 404*b1cdbd2cSJim Jagielski { 405*b1cdbd2cSJim Jagielski // direct draw of PolyPolygon with color 406*b1cdbd2cSJim Jagielski const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor())); 407*b1cdbd2cSJim Jagielski 408*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(aPolygonColor)); 409*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 410*b1cdbd2cSJim Jagielski aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon(); 411*b1cdbd2cSJim Jagielski aLocalPolyPolygon.transform(maCurrentTransformation); 412*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); 413*b1cdbd2cSJim Jagielski } 414*b1cdbd2cSJim Jagielski 415*b1cdbd2cSJim Jagielski // when AA is on and this filled polygons are the result of stroked line geometry, 416*b1cdbd2cSJim Jagielski // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons 417*b1cdbd2cSJim Jagielski // Caution: This is needed in both cases (!) 418*b1cdbd2cSJim Jagielski if(mnPolygonStrokePrimitive2D 419*b1cdbd2cSJim Jagielski && getOptionsDrawinglayer().IsAntiAliasing() 420*b1cdbd2cSJim Jagielski && (mpOutputDevice->GetAntialiasing() & ANTIALIASING_ENABLE_B2DDRAW)) 421*b1cdbd2cSJim Jagielski { 422*b1cdbd2cSJim Jagielski const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor())); 423*b1cdbd2cSJim Jagielski sal_uInt32 nCount(aLocalPolyPolygon.count()); 424*b1cdbd2cSJim Jagielski 425*b1cdbd2cSJim Jagielski if(!nCount) 426*b1cdbd2cSJim Jagielski { 427*b1cdbd2cSJim Jagielski aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon(); 428*b1cdbd2cSJim Jagielski aLocalPolyPolygon.transform(maCurrentTransformation); 429*b1cdbd2cSJim Jagielski nCount = aLocalPolyPolygon.count(); 430*b1cdbd2cSJim Jagielski } 431*b1cdbd2cSJim Jagielski 432*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(); 433*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(Color(aPolygonColor)); 434*b1cdbd2cSJim Jagielski 435*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nCount; a++) 436*b1cdbd2cSJim Jagielski { 437*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aLocalPolyPolygon.getB2DPolygon(a), 0.0); 438*b1cdbd2cSJim Jagielski } 439*b1cdbd2cSJim Jagielski } 440*b1cdbd2cSJim Jagielski 441*b1cdbd2cSJim Jagielski break; 442*b1cdbd2cSJim Jagielski } 443*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D : 444*b1cdbd2cSJim Jagielski { 445*b1cdbd2cSJim Jagielski // #i98289# 446*b1cdbd2cSJim Jagielski const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()); 447*b1cdbd2cSJim Jagielski const sal_uInt16 nOldAntiAliase(mpOutputDevice->GetAntialiasing()); 448*b1cdbd2cSJim Jagielski 449*b1cdbd2cSJim Jagielski if(bForceLineSnap) 450*b1cdbd2cSJim Jagielski { 451*b1cdbd2cSJim Jagielski mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE); 452*b1cdbd2cSJim Jagielski } 453*b1cdbd2cSJim Jagielski 454*b1cdbd2cSJim Jagielski // use new Metafile decomposition 455*b1cdbd2cSJim Jagielski process(rCandidate.get2DDecomposition(getViewInformation2D())); 456*b1cdbd2cSJim Jagielski 457*b1cdbd2cSJim Jagielski if(bForceLineSnap) 458*b1cdbd2cSJim Jagielski { 459*b1cdbd2cSJim Jagielski mpOutputDevice->SetAntialiasing(nOldAntiAliase); 460*b1cdbd2cSJim Jagielski } 461*b1cdbd2cSJim Jagielski 462*b1cdbd2cSJim Jagielski break; 463*b1cdbd2cSJim Jagielski } 464*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_MASKPRIMITIVE2D : 465*b1cdbd2cSJim Jagielski { 466*b1cdbd2cSJim Jagielski // mask group. 467*b1cdbd2cSJim Jagielski RenderMaskPrimitive2DPixel(static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate)); 468*b1cdbd2cSJim Jagielski break; 469*b1cdbd2cSJim Jagielski } 470*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D : 471*b1cdbd2cSJim Jagielski { 472*b1cdbd2cSJim Jagielski // modified color group. Force output to unified color. 473*b1cdbd2cSJim Jagielski RenderModifiedColorPrimitive2D(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate)); 474*b1cdbd2cSJim Jagielski break; 475*b1cdbd2cSJim Jagielski } 476*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D : 477*b1cdbd2cSJim Jagielski { 478*b1cdbd2cSJim Jagielski // Detect if a single PolyPolygonColorPrimitive2D is contained; in that case, 479*b1cdbd2cSJim Jagielski // use the faster OutputDevice::DrawTransparent method 480*b1cdbd2cSJim Jagielski const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate); 481*b1cdbd2cSJim Jagielski const primitive2d::Primitive2DSequence rContent = rUniTransparenceCandidate.getChildren(); 482*b1cdbd2cSJim Jagielski 483*b1cdbd2cSJim Jagielski if(rContent.hasElements()) 484*b1cdbd2cSJim Jagielski { 485*b1cdbd2cSJim Jagielski if(0.0 == rUniTransparenceCandidate.getTransparence()) 486*b1cdbd2cSJim Jagielski { 487*b1cdbd2cSJim Jagielski // not transparent at all, use content 488*b1cdbd2cSJim Jagielski process(rUniTransparenceCandidate.getChildren()); 489*b1cdbd2cSJim Jagielski } 490*b1cdbd2cSJim Jagielski else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0) 491*b1cdbd2cSJim Jagielski { 492*b1cdbd2cSJim Jagielski bool bDrawTransparentUsed(false); 493*b1cdbd2cSJim Jagielski 494*b1cdbd2cSJim Jagielski // since DEV300 m33 DrawTransparent is supported in VCL (for some targets 495*b1cdbd2cSJim Jagielski // natively), so i am now enabling this shortcut 496*b1cdbd2cSJim Jagielski static bool bAllowUsingDrawTransparent(true); 497*b1cdbd2cSJim Jagielski 498*b1cdbd2cSJim Jagielski if(bAllowUsingDrawTransparent && 1 == rContent.getLength()) 499*b1cdbd2cSJim Jagielski { 500*b1cdbd2cSJim Jagielski const primitive2d::Primitive2DReference xReference(rContent[0]); 501*b1cdbd2cSJim Jagielski const primitive2d::BasePrimitive2D* pBasePrimitive = dynamic_cast< const primitive2d::BasePrimitive2D* >(xReference.get()); 502*b1cdbd2cSJim Jagielski 503*b1cdbd2cSJim Jagielski if(pBasePrimitive) 504*b1cdbd2cSJim Jagielski { 505*b1cdbd2cSJim Jagielski switch(pBasePrimitive->getPrimitive2DID()) 506*b1cdbd2cSJim Jagielski { 507*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D: 508*b1cdbd2cSJim Jagielski { 509*b1cdbd2cSJim Jagielski // single transparent PolyPolygon identified, use directly 510*b1cdbd2cSJim Jagielski const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive); 511*b1cdbd2cSJim Jagielski OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 512*b1cdbd2cSJim Jagielski bDrawTransparentUsed = tryDrawPolyPolygonColorPrimitive2DDirect(*pPoPoColor, rUniTransparenceCandidate.getTransparence()); 513*b1cdbd2cSJim Jagielski break; 514*b1cdbd2cSJim Jagielski } 515*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D: 516*b1cdbd2cSJim Jagielski { 517*b1cdbd2cSJim Jagielski // single transparent PolygonHairlinePrimitive2D identified, use directly 518*b1cdbd2cSJim Jagielski const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive); 519*b1cdbd2cSJim Jagielski OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 520*b1cdbd2cSJim Jagielski 521*b1cdbd2cSJim Jagielski // do no tallow by default - problem is that self-overlapping parts of this geometry will 522*b1cdbd2cSJim Jagielski // not be in a all-same transparency but will already alpha-cover themselves with blending. 523*b1cdbd2cSJim Jagielski // This is not what the UnifiedTransparencePrimitive2D defines: It requires all it's 524*b1cdbd2cSJim Jagielski // content to be uniformely transparent. 525*b1cdbd2cSJim Jagielski // For hairline the effect is pretty minimal, but still not correct. 526*b1cdbd2cSJim Jagielski static bool bAllowed(false); 527*b1cdbd2cSJim Jagielski 528*b1cdbd2cSJim Jagielski bDrawTransparentUsed = bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(*pPoHair, rUniTransparenceCandidate.getTransparence()); 529*b1cdbd2cSJim Jagielski break; 530*b1cdbd2cSJim Jagielski } 531*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D: 532*b1cdbd2cSJim Jagielski { 533*b1cdbd2cSJim Jagielski // single transparent PolygonStrokePrimitive2D identified, use directly 534*b1cdbd2cSJim Jagielski const primitive2d::PolygonStrokePrimitive2D* pPoStroke = static_cast< const primitive2d::PolygonStrokePrimitive2D* >(pBasePrimitive); 535*b1cdbd2cSJim Jagielski OSL_ENSURE(pPoStroke, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 536*b1cdbd2cSJim Jagielski 537*b1cdbd2cSJim Jagielski // do no tallow by default - problem is that self-overlapping parts of this geometry will 538*b1cdbd2cSJim Jagielski // not be in a all-same transparency but will already alpha-cover themselves with blending. 539*b1cdbd2cSJim Jagielski // This is not what the UnifiedTransparencePrimitive2D defines: It requires all it's 540*b1cdbd2cSJim Jagielski // content to be uniformely transparent. 541*b1cdbd2cSJim Jagielski // To check, acitvate and draw a wide transparent self-crossing line/curve 542*b1cdbd2cSJim Jagielski static bool bAllowed(false); 543*b1cdbd2cSJim Jagielski 544*b1cdbd2cSJim Jagielski bDrawTransparentUsed = bAllowed && tryDrawPolygonStrokePrimitive2DDirect(*pPoStroke, rUniTransparenceCandidate.getTransparence()); 545*b1cdbd2cSJim Jagielski break; 546*b1cdbd2cSJim Jagielski } 547*b1cdbd2cSJim Jagielski } 548*b1cdbd2cSJim Jagielski } 549*b1cdbd2cSJim Jagielski } 550*b1cdbd2cSJim Jagielski 551*b1cdbd2cSJim Jagielski if(!bDrawTransparentUsed) 552*b1cdbd2cSJim Jagielski { 553*b1cdbd2cSJim Jagielski // unified sub-transparence. Draw to VDev first. 554*b1cdbd2cSJim Jagielski RenderUnifiedTransparencePrimitive2D(rUniTransparenceCandidate); 555*b1cdbd2cSJim Jagielski } 556*b1cdbd2cSJim Jagielski } 557*b1cdbd2cSJim Jagielski } 558*b1cdbd2cSJim Jagielski 559*b1cdbd2cSJim Jagielski break; 560*b1cdbd2cSJim Jagielski } 561*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D : 562*b1cdbd2cSJim Jagielski { 563*b1cdbd2cSJim Jagielski // sub-transparence group. Draw to VDev first. 564*b1cdbd2cSJim Jagielski RenderTransparencePrimitive2D(static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate)); 565*b1cdbd2cSJim Jagielski break; 566*b1cdbd2cSJim Jagielski } 567*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D : 568*b1cdbd2cSJim Jagielski { 569*b1cdbd2cSJim Jagielski // transform group. 570*b1cdbd2cSJim Jagielski RenderTransformPrimitive2D(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate)); 571*b1cdbd2cSJim Jagielski break; 572*b1cdbd2cSJim Jagielski } 573*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D : 574*b1cdbd2cSJim Jagielski { 575*b1cdbd2cSJim Jagielski // new XDrawPage for ViewInformation2D 576*b1cdbd2cSJim Jagielski RenderPagePreviewPrimitive2D(static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate)); 577*b1cdbd2cSJim Jagielski break; 578*b1cdbd2cSJim Jagielski } 579*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D : 580*b1cdbd2cSJim Jagielski { 581*b1cdbd2cSJim Jagielski // marker array 582*b1cdbd2cSJim Jagielski RenderMarkerArrayPrimitive2D(static_cast< const primitive2d::MarkerArrayPrimitive2D& >(rCandidate)); 583*b1cdbd2cSJim Jagielski break; 584*b1cdbd2cSJim Jagielski } 585*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D : 586*b1cdbd2cSJim Jagielski { 587*b1cdbd2cSJim Jagielski // point array 588*b1cdbd2cSJim Jagielski RenderPointArrayPrimitive2D(static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate)); 589*b1cdbd2cSJim Jagielski break; 590*b1cdbd2cSJim Jagielski } 591*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D : 592*b1cdbd2cSJim Jagielski { 593*b1cdbd2cSJim Jagielski // control primitive 594*b1cdbd2cSJim Jagielski const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate); 595*b1cdbd2cSJim Jagielski const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl()); 596*b1cdbd2cSJim Jagielski 597*b1cdbd2cSJim Jagielski try 598*b1cdbd2cSJim Jagielski { 599*b1cdbd2cSJim Jagielski // remember old graphics and create new 600*b1cdbd2cSJim Jagielski uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW); 601*b1cdbd2cSJim Jagielski const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics()); 602*b1cdbd2cSJim Jagielski const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics()); 603*b1cdbd2cSJim Jagielski 604*b1cdbd2cSJim Jagielski if(xNewGraphics.is()) 605*b1cdbd2cSJim Jagielski { 606*b1cdbd2cSJim Jagielski // link graphics and view 607*b1cdbd2cSJim Jagielski xControlView->setGraphics(xNewGraphics); 608*b1cdbd2cSJim Jagielski 609*b1cdbd2cSJim Jagielski // get position 610*b1cdbd2cSJim Jagielski const basegfx::B2DHomMatrix aObjectToPixel(maCurrentTransformation * rControlPrimitive.getTransform()); 611*b1cdbd2cSJim Jagielski const basegfx::B2DPoint aTopLeftPixel(aObjectToPixel * basegfx::B2DPoint(0.0, 0.0)); 612*b1cdbd2cSJim Jagielski 613*b1cdbd2cSJim Jagielski // find out if the control is already visualized as a VCL-ChildWindow. If yes, 614*b1cdbd2cSJim Jagielski // it does not need to be painted at all. 615*b1cdbd2cSJim Jagielski uno::Reference< awt::XWindow2 > xControlWindow(rXControl, uno::UNO_QUERY_THROW); 616*b1cdbd2cSJim Jagielski const bool bControlIsVisibleAsChildWindow(rXControl->getPeer().is() && xControlWindow->isVisible()); 617*b1cdbd2cSJim Jagielski 618*b1cdbd2cSJim Jagielski if(!bControlIsVisibleAsChildWindow) 619*b1cdbd2cSJim Jagielski { 620*b1cdbd2cSJim Jagielski // draw it. Do not forget to use the evtl. offsetted origin of the target device, 621*b1cdbd2cSJim Jagielski // e.g. when used with mask/transparence buffer device 622*b1cdbd2cSJim Jagielski const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin()); 623*b1cdbd2cSJim Jagielski xControlView->draw( 624*b1cdbd2cSJim Jagielski aOrigin.X() + basegfx::fround(aTopLeftPixel.getX()), 625*b1cdbd2cSJim Jagielski aOrigin.Y() + basegfx::fround(aTopLeftPixel.getY())); 626*b1cdbd2cSJim Jagielski } 627*b1cdbd2cSJim Jagielski 628*b1cdbd2cSJim Jagielski // restore original graphics 629*b1cdbd2cSJim Jagielski xControlView->setGraphics(xOriginalGraphics); 630*b1cdbd2cSJim Jagielski } 631*b1cdbd2cSJim Jagielski } 632*b1cdbd2cSJim Jagielski catch(const uno::Exception&) 633*b1cdbd2cSJim Jagielski { 634*b1cdbd2cSJim Jagielski // #i116763# removing since there is a good alternative when the xControlView 635*b1cdbd2cSJim Jagielski // is not found and it is allowed to happen 636*b1cdbd2cSJim Jagielski // DBG_UNHANDLED_EXCEPTION(); 637*b1cdbd2cSJim Jagielski 638*b1cdbd2cSJim Jagielski // process recursively and use the decomposition as Bitmap 639*b1cdbd2cSJim Jagielski process(rCandidate.get2DDecomposition(getViewInformation2D())); 640*b1cdbd2cSJim Jagielski } 641*b1cdbd2cSJim Jagielski 642*b1cdbd2cSJim Jagielski break; 643*b1cdbd2cSJim Jagielski } 644*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D: 645*b1cdbd2cSJim Jagielski { 646*b1cdbd2cSJim Jagielski // try to use directly 647*b1cdbd2cSJim Jagielski const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive2D = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate); 648*b1cdbd2cSJim Jagielski 649*b1cdbd2cSJim Jagielski if(tryDrawPolygonStrokePrimitive2DDirect(rPolygonStrokePrimitive2D, 0.0)) 650*b1cdbd2cSJim Jagielski { 651*b1cdbd2cSJim Jagielski break; 652*b1cdbd2cSJim Jagielski } 653*b1cdbd2cSJim Jagielski 654*b1cdbd2cSJim Jagielski // the stroke primitive may be decomposed to filled polygons. To keep 655*b1cdbd2cSJim Jagielski // evtl. set DrawModes aka DRAWMODE_BLACKLINE, DRAWMODE_GRAYLINE, 656*b1cdbd2cSJim Jagielski // DRAWMODE_GHOSTEDLINE, DRAWMODE_WHITELINE or DRAWMODE_SETTINGSLINE 657*b1cdbd2cSJim Jagielski // working, these need to be copied to the corresponding fill modes 658*b1cdbd2cSJim Jagielski const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 659*b1cdbd2cSJim Jagielski adaptLineToFillDrawMode(); 660*b1cdbd2cSJim Jagielski 661*b1cdbd2cSJim Jagielski // polygon stroke primitive 662*b1cdbd2cSJim Jagielski static bool bSuppressFatToHairlineCorrection(false); 663*b1cdbd2cSJim Jagielski 664*b1cdbd2cSJim Jagielski if(bSuppressFatToHairlineCorrection) 665*b1cdbd2cSJim Jagielski { 666*b1cdbd2cSJim Jagielski // remeber that we enter a PolygonStrokePrimitive2D decomposition, 667*b1cdbd2cSJim Jagielski // used for AA thick line drawing 668*b1cdbd2cSJim Jagielski mnPolygonStrokePrimitive2D++; 669*b1cdbd2cSJim Jagielski 670*b1cdbd2cSJim Jagielski // with AA there is no need to handle thin lines special 671*b1cdbd2cSJim Jagielski process(rCandidate.get2DDecomposition(getViewInformation2D())); 672*b1cdbd2cSJim Jagielski 673*b1cdbd2cSJim Jagielski // leave PolygonStrokePrimitive2D 674*b1cdbd2cSJim Jagielski mnPolygonStrokePrimitive2D--; 675*b1cdbd2cSJim Jagielski } 676*b1cdbd2cSJim Jagielski else 677*b1cdbd2cSJim Jagielski { 678*b1cdbd2cSJim Jagielski // Lines with 1 and 2 pixel width without AA need special treatment since their vsiualisation 679*b1cdbd2cSJim Jagielski // as filled polygons is geometrically corret but looks wrong since polygon filling avoids 680*b1cdbd2cSJim Jagielski // the right and bottom pixels. The used method evaluates that and takes the correct action, 681*b1cdbd2cSJim Jagielski // including calling recursively with decomposition if line is wide enough 682*b1cdbd2cSJim Jagielski RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive2D); 683*b1cdbd2cSJim Jagielski } 684*b1cdbd2cSJim Jagielski 685*b1cdbd2cSJim Jagielski // restore DrawMode 686*b1cdbd2cSJim Jagielski mpOutputDevice->SetDrawMode(nOriginalDrawMode); 687*b1cdbd2cSJim Jagielski 688*b1cdbd2cSJim Jagielski break; 689*b1cdbd2cSJim Jagielski } 690*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D : 691*b1cdbd2cSJim Jagielski { 692*b1cdbd2cSJim Jagielski static bool bForceIgnoreHatchSmoothing(false); 693*b1cdbd2cSJim Jagielski 694*b1cdbd2cSJim Jagielski if(bForceIgnoreHatchSmoothing || getOptionsDrawinglayer().IsAntiAliasing()) 695*b1cdbd2cSJim Jagielski { 696*b1cdbd2cSJim Jagielski // if AA is used (or ignore smoothing is on), there is no need to smooth 697*b1cdbd2cSJim Jagielski // hatch painting, use decomposition 698*b1cdbd2cSJim Jagielski process(rCandidate.get2DDecomposition(getViewInformation2D())); 699*b1cdbd2cSJim Jagielski } 700*b1cdbd2cSJim Jagielski else 701*b1cdbd2cSJim Jagielski { 702*b1cdbd2cSJim Jagielski // without AA, use VCL to draw the hatch. It snaps hatch distances to the next pixel 703*b1cdbd2cSJim Jagielski // and forces hatch distance to be >= 3 pixels to make the hatch display look smoother. 704*b1cdbd2cSJim Jagielski // This is wrong in principle, but looks nicer. This could also be done here directly 705*b1cdbd2cSJim Jagielski // without VCL usage if needed 706*b1cdbd2cSJim Jagielski const primitive2d::FillHatchPrimitive2D& rFillHatchPrimitive = static_cast< const primitive2d::FillHatchPrimitive2D& >(rCandidate); 707*b1cdbd2cSJim Jagielski const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch(); 708*b1cdbd2cSJim Jagielski 709*b1cdbd2cSJim Jagielski // create hatch polygon in range size and discrete coordinates 710*b1cdbd2cSJim Jagielski basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getObjectRange()); 711*b1cdbd2cSJim Jagielski aHatchRange.transform(maCurrentTransformation); 712*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon aHatchPolygon(basegfx::tools::createPolygonFromRect(aHatchRange)); 713*b1cdbd2cSJim Jagielski 714*b1cdbd2cSJim Jagielski if(rFillHatchAttributes.isFillBackground()) 715*b1cdbd2cSJim Jagielski { 716*b1cdbd2cSJim Jagielski // #i111846# background fill is active; draw fill polygon 717*b1cdbd2cSJim Jagielski const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor())); 718*b1cdbd2cSJim Jagielski 719*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(aPolygonColor)); 720*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 721*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolygon(aHatchPolygon); 722*b1cdbd2cSJim Jagielski } 723*b1cdbd2cSJim Jagielski 724*b1cdbd2cSJim Jagielski // set hatch line color 725*b1cdbd2cSJim Jagielski const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor())); 726*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(); 727*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(Color(aHatchColor)); 728*b1cdbd2cSJim Jagielski 729*b1cdbd2cSJim Jagielski // get hatch style 730*b1cdbd2cSJim Jagielski HatchStyle eHatchStyle(HATCH_SINGLE); 731*b1cdbd2cSJim Jagielski 732*b1cdbd2cSJim Jagielski switch(rFillHatchAttributes.getStyle()) 733*b1cdbd2cSJim Jagielski { 734*b1cdbd2cSJim Jagielski default : // HATCHSTYLE_SINGLE 735*b1cdbd2cSJim Jagielski { 736*b1cdbd2cSJim Jagielski break; 737*b1cdbd2cSJim Jagielski } 738*b1cdbd2cSJim Jagielski case attribute::HATCHSTYLE_DOUBLE : 739*b1cdbd2cSJim Jagielski { 740*b1cdbd2cSJim Jagielski eHatchStyle = HATCH_DOUBLE; 741*b1cdbd2cSJim Jagielski break; 742*b1cdbd2cSJim Jagielski } 743*b1cdbd2cSJim Jagielski case attribute::HATCHSTYLE_TRIPLE : 744*b1cdbd2cSJim Jagielski { 745*b1cdbd2cSJim Jagielski eHatchStyle = HATCH_TRIPLE; 746*b1cdbd2cSJim Jagielski break; 747*b1cdbd2cSJim Jagielski } 748*b1cdbd2cSJim Jagielski } 749*b1cdbd2cSJim Jagielski 750*b1cdbd2cSJim Jagielski // create hatch 751*b1cdbd2cSJim Jagielski const basegfx::B2DVector aDiscreteDistance(maCurrentTransformation * basegfx::B2DVector(rFillHatchAttributes.getDistance(), 0.0)); 752*b1cdbd2cSJim Jagielski const sal_uInt32 nDistance(basegfx::fround(aDiscreteDistance.getLength())); 753*b1cdbd2cSJim Jagielski const sal_uInt16 nAngle10((sal_uInt16)basegfx::fround(rFillHatchAttributes.getAngle() / F_PI1800)); 754*b1cdbd2cSJim Jagielski ::Hatch aVCLHatch(eHatchStyle, Color(rFillHatchAttributes.getColor()), nDistance, nAngle10); 755*b1cdbd2cSJim Jagielski 756*b1cdbd2cSJim Jagielski // draw hatch using VCL 757*b1cdbd2cSJim Jagielski mpOutputDevice->DrawHatch(PolyPolygon(Polygon(aHatchPolygon)), aVCLHatch); 758*b1cdbd2cSJim Jagielski } 759*b1cdbd2cSJim Jagielski break; 760*b1cdbd2cSJim Jagielski } 761*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D : 762*b1cdbd2cSJim Jagielski { 763*b1cdbd2cSJim Jagielski // #i98404# Handle directly, especially when AA is active 764*b1cdbd2cSJim Jagielski const primitive2d::BackgroundColorPrimitive2D& rPrimitive = static_cast< const primitive2d::BackgroundColorPrimitive2D& >(rCandidate); 765*b1cdbd2cSJim Jagielski const sal_uInt16 nOriginalAA(mpOutputDevice->GetAntialiasing()); 766*b1cdbd2cSJim Jagielski 767*b1cdbd2cSJim Jagielski // switch AA off in all cases 768*b1cdbd2cSJim Jagielski mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 769*b1cdbd2cSJim Jagielski 770*b1cdbd2cSJim Jagielski // create color for fill 771*b1cdbd2cSJim Jagielski const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor())); 772*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(aPolygonColor)); 773*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 774*b1cdbd2cSJim Jagielski 775*b1cdbd2cSJim Jagielski // create rectangle for fill 776*b1cdbd2cSJim Jagielski const basegfx::B2DRange& aViewport(getViewInformation2D().getDiscreteViewport()); 777*b1cdbd2cSJim Jagielski const Rectangle aRectangle( 778*b1cdbd2cSJim Jagielski (sal_Int32)floor(aViewport.getMinX()), (sal_Int32)floor(aViewport.getMinY()), 779*b1cdbd2cSJim Jagielski (sal_Int32)ceil(aViewport.getMaxX()), (sal_Int32)ceil(aViewport.getMaxY())); 780*b1cdbd2cSJim Jagielski mpOutputDevice->DrawRect(aRectangle); 781*b1cdbd2cSJim Jagielski 782*b1cdbd2cSJim Jagielski // restore AA setting 783*b1cdbd2cSJim Jagielski mpOutputDevice->SetAntialiasing(nOriginalAA); 784*b1cdbd2cSJim Jagielski break; 785*b1cdbd2cSJim Jagielski } 786*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D : 787*b1cdbd2cSJim Jagielski { 788*b1cdbd2cSJim Jagielski // #i97628# 789*b1cdbd2cSJim Jagielski // This primitive means that the content is derived from an active text edit, 790*b1cdbd2cSJim Jagielski // not from model data itself. Some renderers need to suppress this content, e.g. 791*b1cdbd2cSJim Jagielski // the pixel renderer used for displaying the edit view (like this one). It's 792*b1cdbd2cSJim Jagielski // not to be suppressed by the MetaFile renderers, so that the edited text is 793*b1cdbd2cSJim Jagielski // part of the MetaFile, e.g. needed for presentation previews. 794*b1cdbd2cSJim Jagielski // Action: Ignore here, do nothing. 795*b1cdbd2cSJim Jagielski break; 796*b1cdbd2cSJim Jagielski } 797*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_INVERTPRIMITIVE2D : 798*b1cdbd2cSJim Jagielski { 799*b1cdbd2cSJim Jagielski // invert primitive (currently only used for HighContrast fallback for selection in SW and SC). 800*b1cdbd2cSJim Jagielski // Set OutDev to XOR and switch AA off (XOR does not work with AA) 801*b1cdbd2cSJim Jagielski mpOutputDevice->Push(); 802*b1cdbd2cSJim Jagielski mpOutputDevice->SetRasterOp( ROP_XOR ); 803*b1cdbd2cSJim Jagielski const sal_uInt16 nAntiAliasing(mpOutputDevice->GetAntialiasing()); 804*b1cdbd2cSJim Jagielski mpOutputDevice->SetAntialiasing(nAntiAliasing & ~ANTIALIASING_ENABLE_B2DDRAW); 805*b1cdbd2cSJim Jagielski 806*b1cdbd2cSJim Jagielski // process content recursively 807*b1cdbd2cSJim Jagielski process(rCandidate.get2DDecomposition(getViewInformation2D())); 808*b1cdbd2cSJim Jagielski 809*b1cdbd2cSJim Jagielski // restore OutDev 810*b1cdbd2cSJim Jagielski mpOutputDevice->Pop(); 811*b1cdbd2cSJim Jagielski mpOutputDevice->SetAntialiasing(nAntiAliasing); 812*b1cdbd2cSJim Jagielski break; 813*b1cdbd2cSJim Jagielski } 814*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_EPSPRIMITIVE2D : 815*b1cdbd2cSJim Jagielski { 816*b1cdbd2cSJim Jagielski RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); 817*b1cdbd2cSJim Jagielski break; 818*b1cdbd2cSJim Jagielski } 819*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_SVGLINEARATOMPRIMITIVE2D: 820*b1cdbd2cSJim Jagielski { 821*b1cdbd2cSJim Jagielski RenderSvgLinearAtomPrimitive2D(static_cast< const primitive2d::SvgLinearAtomPrimitive2D& >(rCandidate)); 822*b1cdbd2cSJim Jagielski break; 823*b1cdbd2cSJim Jagielski } 824*b1cdbd2cSJim Jagielski case PRIMITIVE2D_ID_SVGRADIALATOMPRIMITIVE2D: 825*b1cdbd2cSJim Jagielski { 826*b1cdbd2cSJim Jagielski RenderSvgRadialAtomPrimitive2D(static_cast< const primitive2d::SvgRadialAtomPrimitive2D& >(rCandidate)); 827*b1cdbd2cSJim Jagielski break; 828*b1cdbd2cSJim Jagielski } 829*b1cdbd2cSJim Jagielski default : 830*b1cdbd2cSJim Jagielski { 831*b1cdbd2cSJim Jagielski // process recursively 832*b1cdbd2cSJim Jagielski process(rCandidate.get2DDecomposition(getViewInformation2D())); 833*b1cdbd2cSJim Jagielski break; 834*b1cdbd2cSJim Jagielski } 835*b1cdbd2cSJim Jagielski } 836*b1cdbd2cSJim Jagielski } 837*b1cdbd2cSJim Jagielski } // end of namespace processor2d 838*b1cdbd2cSJim Jagielski } // end of namespace drawinglayer 839*b1cdbd2cSJim Jagielski 840*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 841*b1cdbd2cSJim Jagielski // eof 842