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