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 10cdf0e10cSrcweir * 11464702f4SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 20464702f4SAndrew Rist *************************************************************/ 21464702f4SAndrew Rist 22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 23cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 24cdf0e10cSrcweir 25cdf0e10cSrcweir #include <drawinglayer/processor2d/vclpixelprocessor2d.hxx> 26cdf0e10cSrcweir #include <vcl/outdev.hxx> 27cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 28cdf0e10cSrcweir #include <drawinglayer/primitive2d/textprimitive2d.hxx> 29cdf0e10cSrcweir #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 30cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 31cdf0e10cSrcweir #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 32035a2f44SArmin Le Grand #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx> 33cdf0e10cSrcweir #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> 34cdf0e10cSrcweir #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 35cdf0e10cSrcweir #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> 36cdf0e10cSrcweir #include <drawinglayer/primitive2d/transparenceprimitive2d.hxx> 37cdf0e10cSrcweir #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 38cdf0e10cSrcweir #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> 39cdf0e10cSrcweir #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx> 40cdf0e10cSrcweir #include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx> 41cdf0e10cSrcweir #include <drawinglayer/primitive2d/controlprimitive2d.hxx> 42cdf0e10cSrcweir #include <com/sun/star/awt/XWindow2.hpp> 43cdf0e10cSrcweir #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 44cdf0e10cSrcweir #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> 45cdf0e10cSrcweir #include <helperwrongspellrenderer.hxx> 46cdf0e10cSrcweir #include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx> 47cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 48cdf0e10cSrcweir #include <vcl/hatch.hxx> 49cdf0e10cSrcweir #include <tools/diagnose_ex.h> 50cdf0e10cSrcweir #include <com/sun/star/awt/PosSize.hpp> 51cdf0e10cSrcweir #include <drawinglayer/primitive2d/invertprimitive2d.hxx> 52cdf0e10cSrcweir #include <cstdio> 53cdf0e10cSrcweir #include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> 54cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx> 55cdf0e10cSrcweir #include <drawinglayer/primitive2d/epsprimitive2d.hxx> 5639551d71SArmin Le Grand #include <drawinglayer/primitive2d/svggradientprimitive2d.hxx> 57cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx> 58cdf0e10cSrcweir #include <vcl/window.hxx> 59cdf0e10cSrcweir 60cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 61cdf0e10cSrcweir 62cdf0e10cSrcweir using namespace com::sun::star; 63cdf0e10cSrcweir 64cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 65cdf0e10cSrcweir 66cdf0e10cSrcweir namespace drawinglayer 67cdf0e10cSrcweir { 68cdf0e10cSrcweir namespace processor2d 69cdf0e10cSrcweir { VclPixelProcessor2D(const geometry::ViewInformation2D & rViewInformation,OutputDevice & rOutDev)70cdf0e10cSrcweir VclPixelProcessor2D::VclPixelProcessor2D(const geometry::ViewInformation2D& rViewInformation, OutputDevice& rOutDev) 71401c91d1SArmin Le Grand : VclProcessor2D(rViewInformation, rOutDev) 72cdf0e10cSrcweir { 73cdf0e10cSrcweir // prepare maCurrentTransformation matrix with viewTransformation to target directly to pixels 74cdf0e10cSrcweir maCurrentTransformation = rViewInformation.getObjectToViewTransformation(); 75cdf0e10cSrcweir 76cdf0e10cSrcweir // prepare output directly to pixels 77cdf0e10cSrcweir mpOutputDevice->Push(PUSH_MAPMODE); 78cdf0e10cSrcweir mpOutputDevice->SetMapMode(); 79cdf0e10cSrcweir 80cdf0e10cSrcweir // react on AntiAliasing settings 81cdf0e10cSrcweir if(getOptionsDrawinglayer().IsAntiAliasing()) 82cdf0e10cSrcweir { 83cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW); 84cdf0e10cSrcweir } 85cdf0e10cSrcweir else 86cdf0e10cSrcweir { 87cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 88cdf0e10cSrcweir } 89cdf0e10cSrcweir } 90cdf0e10cSrcweir ~VclPixelProcessor2D()91cdf0e10cSrcweir VclPixelProcessor2D::~VclPixelProcessor2D() 92cdf0e10cSrcweir { 93cdf0e10cSrcweir // restore MapMode 94cdf0e10cSrcweir mpOutputDevice->Pop(); 95cdf0e10cSrcweir 96cdf0e10cSrcweir // restore AntiAliasing 97cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 98cdf0e10cSrcweir } 99cdf0e10cSrcweir tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D & rSource,double fTransparency)1000f1c4fd1SArmin Le Grand bool VclPixelProcessor2D::tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D& rSource, double fTransparency) 1010f1c4fd1SArmin Le Grand { 1020f1c4fd1SArmin Le Grand basegfx::B2DPolyPolygon aLocalPolyPolygon(rSource.getB2DPolyPolygon()); 1030f1c4fd1SArmin Le Grand 1040f1c4fd1SArmin Le Grand if(!aLocalPolyPolygon.count()) 1050f1c4fd1SArmin Le Grand { 1060f1c4fd1SArmin Le Grand // no geometry, done 1070f1c4fd1SArmin Le Grand return true; 1080f1c4fd1SArmin Le Grand } 1090f1c4fd1SArmin Le Grand 1100f1c4fd1SArmin Le Grand const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rSource.getBColor())); 1110f1c4fd1SArmin Le Grand 1120f1c4fd1SArmin Le Grand mpOutputDevice->SetFillColor(Color(aPolygonColor)); 1130f1c4fd1SArmin Le Grand mpOutputDevice->SetLineColor(); 1140f1c4fd1SArmin Le Grand aLocalPolyPolygon.transform(maCurrentTransformation); 1150f1c4fd1SArmin Le Grand mpOutputDevice->DrawTransparent( 1160f1c4fd1SArmin Le Grand aLocalPolyPolygon, 1170f1c4fd1SArmin Le Grand fTransparency); 1180f1c4fd1SArmin Le Grand 1190f1c4fd1SArmin Le Grand return true; 1200f1c4fd1SArmin Le Grand } 1210f1c4fd1SArmin Le Grand tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D & rSource,double fTransparency)1220f1c4fd1SArmin Le Grand bool VclPixelProcessor2D::tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D& rSource, double fTransparency) 1230f1c4fd1SArmin Le Grand { 1240f1c4fd1SArmin Le Grand basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon()); 1250f1c4fd1SArmin Le Grand 1260f1c4fd1SArmin Le Grand if(!aLocalPolygon.count()) 1270f1c4fd1SArmin Le Grand { 1280f1c4fd1SArmin Le Grand // no geometry, done 1290f1c4fd1SArmin Le Grand return true; 1300f1c4fd1SArmin Le Grand } 1310f1c4fd1SArmin Le Grand 1320f1c4fd1SArmin Le Grand const basegfx::BColor aLineColor(maBColorModifierStack.getModifiedColor(rSource.getBColor())); 1330f1c4fd1SArmin Le Grand 1340f1c4fd1SArmin Le Grand mpOutputDevice->SetFillColor(); 1350f1c4fd1SArmin Le Grand mpOutputDevice->SetLineColor(Color(aLineColor)); 1360f1c4fd1SArmin Le Grand aLocalPolygon.transform(maCurrentTransformation); 1370f1c4fd1SArmin Le Grand 1380f1c4fd1SArmin Le Grand // try drawing; if it did not work, use standard fallback 1390f1c4fd1SArmin Le Grand if(mpOutputDevice->TryDrawPolyLineDirect( 1400f1c4fd1SArmin Le Grand aLocalPolygon, 1410f1c4fd1SArmin Le Grand 0.0, 1420f1c4fd1SArmin Le Grand fTransparency)) 1430f1c4fd1SArmin Le Grand { 1440f1c4fd1SArmin Le Grand return true; 1450f1c4fd1SArmin Le Grand } 1460f1c4fd1SArmin Le Grand 1470f1c4fd1SArmin Le Grand return false; 1480f1c4fd1SArmin Le Grand } 1490f1c4fd1SArmin Le Grand tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D & rSource,double fTransparency)1500f1c4fd1SArmin Le Grand bool VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D& rSource, double fTransparency) 1510f1c4fd1SArmin Le Grand { 1520f1c4fd1SArmin Le Grand basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon()); 1530f1c4fd1SArmin Le Grand 1540f1c4fd1SArmin Le Grand if(!aLocalPolygon.count()) 1550f1c4fd1SArmin Le Grand { 1560f1c4fd1SArmin Le Grand // no geometry, done 1570f1c4fd1SArmin Le Grand return true; 1580f1c4fd1SArmin Le Grand } 1590f1c4fd1SArmin Le Grand 1600f1c4fd1SArmin Le Grand aLocalPolygon = basegfx::tools::simplifyCurveSegments(aLocalPolygon); 1610f1c4fd1SArmin Le Grand basegfx::B2DPolyPolygon aHairLinePolyPolygon; 1620f1c4fd1SArmin Le Grand 1630f1c4fd1SArmin Le Grand if(rSource.getStrokeAttribute().isDefault() || 0.0 == rSource.getStrokeAttribute().getFullDotDashLen()) 1640f1c4fd1SArmin Le Grand { 1650f1c4fd1SArmin Le Grand // no line dashing, just copy 1660f1c4fd1SArmin Le Grand aHairLinePolyPolygon.append(aLocalPolygon); 1670f1c4fd1SArmin Le Grand } 1680f1c4fd1SArmin Le Grand else 1690f1c4fd1SArmin Le Grand { 1700f1c4fd1SArmin Le Grand // apply LineStyle 1710f1c4fd1SArmin Le Grand basegfx::tools::applyLineDashing( 1720f1c4fd1SArmin Le Grand aLocalPolygon, 1730f1c4fd1SArmin Le Grand rSource.getStrokeAttribute().getDotDashArray(), 1740f1c4fd1SArmin Le Grand &aHairLinePolyPolygon, 1750f1c4fd1SArmin Le Grand 0, 1760f1c4fd1SArmin Le Grand rSource.getStrokeAttribute().getFullDotDashLen()); 1770f1c4fd1SArmin Le Grand } 1780f1c4fd1SArmin Le Grand 1790f1c4fd1SArmin Le Grand if(!aHairLinePolyPolygon.count()) 1800f1c4fd1SArmin Le Grand { 1810f1c4fd1SArmin Le Grand // no geometry, done 1820f1c4fd1SArmin Le Grand return true; 1830f1c4fd1SArmin Le Grand } 1840f1c4fd1SArmin Le Grand 1850f1c4fd1SArmin Le Grand const basegfx::BColor aLineColor( 1860f1c4fd1SArmin Le Grand maBColorModifierStack.getModifiedColor( 1870f1c4fd1SArmin Le Grand rSource.getLineAttribute().getColor())); 1880f1c4fd1SArmin Le Grand 1890f1c4fd1SArmin Le Grand mpOutputDevice->SetFillColor(); 1900f1c4fd1SArmin Le Grand mpOutputDevice->SetLineColor(Color(aLineColor)); 1910f1c4fd1SArmin Le Grand aHairLinePolyPolygon.transform(maCurrentTransformation); 1920f1c4fd1SArmin Le Grand 1930f1c4fd1SArmin Le Grand double fLineWidth(rSource.getLineAttribute().getWidth()); 1940f1c4fd1SArmin Le Grand 1950f1c4fd1SArmin Le Grand if(basegfx::fTools::more(fLineWidth, 0.0)) 1960f1c4fd1SArmin Le Grand { 1970f1c4fd1SArmin Le Grand basegfx::B2DVector aLineWidth(fLineWidth, 0.0); 1980f1c4fd1SArmin Le Grand 1990f1c4fd1SArmin Le Grand aLineWidth = maCurrentTransformation * aLineWidth; 2000f1c4fd1SArmin Le Grand fLineWidth = aLineWidth.getLength(); 2010f1c4fd1SArmin Le Grand } 2020f1c4fd1SArmin Le Grand 2030f1c4fd1SArmin Le Grand bool bHasPoints(false); 2040f1c4fd1SArmin Le Grand bool bTryWorked(false); 2050f1c4fd1SArmin Le Grand 2060f1c4fd1SArmin Le Grand for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++) 2070f1c4fd1SArmin Le Grand { 2080f1c4fd1SArmin Le Grand const basegfx::B2DPolygon aSingle(aHairLinePolyPolygon.getB2DPolygon(a)); 2090f1c4fd1SArmin Le Grand 2100f1c4fd1SArmin Le Grand if(aSingle.count()) 2110f1c4fd1SArmin Le Grand { 2120f1c4fd1SArmin Le Grand bHasPoints = true; 2130f1c4fd1SArmin Le Grand 2140f1c4fd1SArmin Le Grand if(mpOutputDevice->TryDrawPolyLineDirect( 2150f1c4fd1SArmin Le Grand aSingle, 2160f1c4fd1SArmin Le Grand fLineWidth, 2170f1c4fd1SArmin Le Grand fTransparency, 2180f1c4fd1SArmin Le Grand rSource.getLineAttribute().getLineJoin(), 2190f1c4fd1SArmin Le Grand rSource.getLineAttribute().getLineCap())) 2200f1c4fd1SArmin Le Grand { 2210f1c4fd1SArmin Le Grand bTryWorked = true; 2220f1c4fd1SArmin Le Grand } 2230f1c4fd1SArmin Le Grand } 2240f1c4fd1SArmin Le Grand } 2250f1c4fd1SArmin Le Grand 2260f1c4fd1SArmin Le Grand if(!bTryWorked && !bHasPoints) 2270f1c4fd1SArmin Le Grand { 2280f1c4fd1SArmin Le Grand // no geometry despite try 2290f1c4fd1SArmin Le Grand bTryWorked = true; 2300f1c4fd1SArmin Le Grand } 2310f1c4fd1SArmin Le Grand 2320f1c4fd1SArmin Le Grand return bTryWorked; 2330f1c4fd1SArmin Le Grand } 2340f1c4fd1SArmin Le Grand processBasePrimitive2D(const primitive2d::BasePrimitive2D & rCandidate)235cdf0e10cSrcweir void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) 236cdf0e10cSrcweir { 237cdf0e10cSrcweir switch(rCandidate.getPrimitive2DID()) 238cdf0e10cSrcweir { 239cdf0e10cSrcweir case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : 240cdf0e10cSrcweir { 241cdf0e10cSrcweir // directdraw of wrong spell primitive; added test possibility to check wrong spell decompose 242cdf0e10cSrcweir static bool bHandleWrongSpellDirectly(true); 243cdf0e10cSrcweir 244cdf0e10cSrcweir if(bHandleWrongSpellDirectly) 245cdf0e10cSrcweir { 246cdf0e10cSrcweir const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive = static_cast< const primitive2d::WrongSpellPrimitive2D& >(rCandidate); 247cdf0e10cSrcweir 248cdf0e10cSrcweir if(!renderWrongSpellPrimitive2D( 249cdf0e10cSrcweir rWrongSpellPrimitive, 250cdf0e10cSrcweir *mpOutputDevice, 251cdf0e10cSrcweir maCurrentTransformation, 252cdf0e10cSrcweir maBColorModifierStack)) 253cdf0e10cSrcweir { 254cdf0e10cSrcweir // fallback to decomposition (MetaFile) 255cdf0e10cSrcweir process(rWrongSpellPrimitive.get2DDecomposition(getViewInformation2D())); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir } 258cdf0e10cSrcweir else 259cdf0e10cSrcweir { 260cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 261cdf0e10cSrcweir } 262cdf0e10cSrcweir break; 263cdf0e10cSrcweir } 264cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D : 265cdf0e10cSrcweir { 266cdf0e10cSrcweir // directdraw of text simple portion; added test possibility to check text decompose 267cdf0e10cSrcweir static bool bForceSimpleTextDecomposition(false); 268cdf0e10cSrcweir 269cdf0e10cSrcweir // Adapt evtl. used special DrawMode 270cdf0e10cSrcweir const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 271cdf0e10cSrcweir adaptTextToFillDrawMode(); 272cdf0e10cSrcweir 273cdf0e10cSrcweir if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect()) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); 276cdf0e10cSrcweir } 277cdf0e10cSrcweir else 278cdf0e10cSrcweir { 279cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 280cdf0e10cSrcweir } 281cdf0e10cSrcweir 282cdf0e10cSrcweir // restore DrawMode 283cdf0e10cSrcweir mpOutputDevice->SetDrawMode(nOriginalDrawMode); 284cdf0e10cSrcweir 285cdf0e10cSrcweir break; 286cdf0e10cSrcweir } 287cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D : 288cdf0e10cSrcweir { 289cdf0e10cSrcweir // directdraw of text simple portion; added test possibility to check text decompose 290cdf0e10cSrcweir static bool bForceComplexTextDecomposition(false); 291cdf0e10cSrcweir 292cdf0e10cSrcweir // Adapt evtl. used special DrawMode 293cdf0e10cSrcweir const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 294cdf0e10cSrcweir adaptTextToFillDrawMode(); 295cdf0e10cSrcweir 296cdf0e10cSrcweir if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect()) 297cdf0e10cSrcweir { 298cdf0e10cSrcweir RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); 299cdf0e10cSrcweir } 300cdf0e10cSrcweir else 301cdf0e10cSrcweir { 302cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 303cdf0e10cSrcweir } 304cdf0e10cSrcweir 305cdf0e10cSrcweir // restore DrawMode 306cdf0e10cSrcweir mpOutputDevice->SetDrawMode(nOriginalDrawMode); 307cdf0e10cSrcweir 308cdf0e10cSrcweir break; 309cdf0e10cSrcweir } 310cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : 311cdf0e10cSrcweir { 3120f1c4fd1SArmin Le Grand // try to use directly 3130f1c4fd1SArmin Le Grand const primitive2d::PolygonHairlinePrimitive2D& rPolygonHairlinePrimitive2D = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate); 3140f1c4fd1SArmin Le Grand static bool bAllowed(true); 3150f1c4fd1SArmin Le Grand 3160f1c4fd1SArmin Le Grand if(bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(rPolygonHairlinePrimitive2D, 0.0)) 3170f1c4fd1SArmin Le Grand { 3180f1c4fd1SArmin Le Grand break; 3190f1c4fd1SArmin Le Grand } 3200f1c4fd1SArmin Le Grand 321cdf0e10cSrcweir // direct draw of hairline 3220f1c4fd1SArmin Le Grand RenderPolygonHairlinePrimitive2D(rPolygonHairlinePrimitive2D, true); 323cdf0e10cSrcweir break; 324cdf0e10cSrcweir } 325cdf0e10cSrcweir case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D : 326cdf0e10cSrcweir { 327cdf0e10cSrcweir // direct draw of transformed BitmapEx primitive 328cf95e506SArmin Le Grand const primitive2d::BitmapPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate); 329cf95e506SArmin Le Grand 330cf95e506SArmin Le Grand // check if graphic content is inside discrete local ViewPort 331cf95e506SArmin Le Grand const basegfx::B2DRange& rDiscreteViewPort(getViewInformation2D().getDiscreteViewport()); 332cf95e506SArmin Le Grand const basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rBitmapCandidate.getTransform()); 333cf95e506SArmin Le Grand 334cf95e506SArmin Le Grand if(!rDiscreteViewPort.isEmpty()) 335cf95e506SArmin Le Grand { 336cf95e506SArmin Le Grand basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0); 337cf95e506SArmin Le Grand 338cf95e506SArmin Le Grand aUnitRange.transform(aLocalTransform); 339cf95e506SArmin Le Grand 340cf95e506SArmin Le Grand if(!aUnitRange.overlaps(rDiscreteViewPort)) 341cf95e506SArmin Le Grand { 342cf95e506SArmin Le Grand // content is outside discrete local ViewPort 343cf95e506SArmin Le Grand break; 344cf95e506SArmin Le Grand } 345cf95e506SArmin Le Grand } 346cf95e506SArmin Le Grand 347cdf0e10cSrcweir RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate)); 348cdf0e10cSrcweir break; 349cdf0e10cSrcweir } 350035a2f44SArmin Le Grand case PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D : 351cdf0e10cSrcweir { 352cdf0e10cSrcweir // direct draw of fillBitmapPrimitive 353035a2f44SArmin Le Grand RenderFillGraphicPrimitive2D(static_cast< const primitive2d::FillGraphicPrimitive2D& >(rCandidate)); 354cdf0e10cSrcweir break; 355cdf0e10cSrcweir } 356cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D : 357cdf0e10cSrcweir { 358cdf0e10cSrcweir // direct draw of gradient 3592af35ee2SArmin Le Grand const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate = static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate); 3602af35ee2SArmin Le Grand const attribute::FillGradientAttribute& rGradient(rPolygonCandidate.getFillGradient()); 3612af35ee2SArmin Le Grand basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor())); 3622af35ee2SArmin Le Grand basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor())); 3632af35ee2SArmin Le Grand basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon()); 3642af35ee2SArmin Le Grand 3652af35ee2SArmin Le Grand if(aLocalPolyPolygon.count()) 3662af35ee2SArmin Le Grand { 3672af35ee2SArmin Le Grand aLocalPolyPolygon.transform(maCurrentTransformation); 3682af35ee2SArmin Le Grand 3692af35ee2SArmin Le Grand if(aStartColor == aEndColor) 3702af35ee2SArmin Le Grand { 3712af35ee2SArmin Le Grand // no gradient at all, draw as polygon in AA and non-AA case 3722af35ee2SArmin Le Grand mpOutputDevice->SetLineColor(); 3732af35ee2SArmin Le Grand mpOutputDevice->SetFillColor(Color(aStartColor)); 3742af35ee2SArmin Le Grand mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); 3752af35ee2SArmin Le Grand } 3762af35ee2SArmin Le Grand else 3772af35ee2SArmin Le Grand { 3782af35ee2SArmin Le Grand // use the primitive decomposition of the metafile 3792af35ee2SArmin Le Grand process(rPolygonCandidate.get2DDecomposition(getViewInformation2D())); 3802af35ee2SArmin Le Grand } 3812af35ee2SArmin Le Grand } 382cdf0e10cSrcweir break; 383cdf0e10cSrcweir } 384035a2f44SArmin Le Grand case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D : 385cdf0e10cSrcweir { 386cdf0e10cSrcweir // direct draw of bitmap 387035a2f44SArmin Le Grand RenderPolyPolygonGraphicPrimitive2D(static_cast< const primitive2d::PolyPolygonGraphicPrimitive2D& >(rCandidate)); 388cdf0e10cSrcweir break; 389cdf0e10cSrcweir } 390cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D : 391cdf0e10cSrcweir { 3920f1c4fd1SArmin Le Grand // try to use directly 3930f1c4fd1SArmin Le Grand const primitive2d::PolyPolygonColorPrimitive2D& rPolyPolygonColorPrimitive2D = static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate); 3940f1c4fd1SArmin Le Grand basegfx::B2DPolyPolygon aLocalPolyPolygon; 3950f1c4fd1SArmin Le Grand static bool bAllowed(true); 3960f1c4fd1SArmin Le Grand 3970f1c4fd1SArmin Le Grand if(bAllowed && tryDrawPolyPolygonColorPrimitive2DDirect(rPolyPolygonColorPrimitive2D, 0.0)) 3980f1c4fd1SArmin Le Grand { 3990f1c4fd1SArmin Le Grand // okay, done. In this case no gaps should have to be repaired, too 4000f1c4fd1SArmin Le Grand } 4010f1c4fd1SArmin Le Grand else 4020f1c4fd1SArmin Le Grand { 403cdf0e10cSrcweir // direct draw of PolyPolygon with color 4040f1c4fd1SArmin Le Grand const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor())); 4050f1c4fd1SArmin Le Grand 4060f1c4fd1SArmin Le Grand mpOutputDevice->SetFillColor(Color(aPolygonColor)); 4070f1c4fd1SArmin Le Grand mpOutputDevice->SetLineColor(); 4080f1c4fd1SArmin Le Grand aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon(); 4090f1c4fd1SArmin Le Grand aLocalPolyPolygon.transform(maCurrentTransformation); 4100f1c4fd1SArmin Le Grand mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); 4110f1c4fd1SArmin Le Grand } 4120f1c4fd1SArmin Le Grand 4130f1c4fd1SArmin Le Grand // when AA is on and this filled polygons are the result of stroked line geometry, 4140f1c4fd1SArmin Le Grand // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons 4150f1c4fd1SArmin Le Grand // Caution: This is needed in both cases (!) 4160f1c4fd1SArmin Le Grand if(mnPolygonStrokePrimitive2D 4170f1c4fd1SArmin Le Grand && getOptionsDrawinglayer().IsAntiAliasing() 4180f1c4fd1SArmin Le Grand && (mpOutputDevice->GetAntialiasing() & ANTIALIASING_ENABLE_B2DDRAW)) 4190f1c4fd1SArmin Le Grand { 4200f1c4fd1SArmin Le Grand const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor())); 4210f1c4fd1SArmin Le Grand sal_uInt32 nCount(aLocalPolyPolygon.count()); 4220f1c4fd1SArmin Le Grand 4230f1c4fd1SArmin Le Grand if(!nCount) 4240f1c4fd1SArmin Le Grand { 4250f1c4fd1SArmin Le Grand aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon(); 4260f1c4fd1SArmin Le Grand aLocalPolyPolygon.transform(maCurrentTransformation); 4270f1c4fd1SArmin Le Grand nCount = aLocalPolyPolygon.count(); 4280f1c4fd1SArmin Le Grand } 4290f1c4fd1SArmin Le Grand 4300f1c4fd1SArmin Le Grand mpOutputDevice->SetFillColor(); 4310f1c4fd1SArmin Le Grand mpOutputDevice->SetLineColor(Color(aPolygonColor)); 4320f1c4fd1SArmin Le Grand 4330f1c4fd1SArmin Le Grand for(sal_uInt32 a(0); a < nCount; a++) 4340f1c4fd1SArmin Le Grand { 4350f1c4fd1SArmin Le Grand mpOutputDevice->DrawPolyLine(aLocalPolyPolygon.getB2DPolygon(a), 0.0); 4360f1c4fd1SArmin Le Grand } 4370f1c4fd1SArmin Le Grand } 4380f1c4fd1SArmin Le Grand 439cdf0e10cSrcweir break; 440cdf0e10cSrcweir } 441cdf0e10cSrcweir case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D : 442cdf0e10cSrcweir { 443cdf0e10cSrcweir // #i98289# 444cdf0e10cSrcweir const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()); 445cdf0e10cSrcweir const sal_uInt16 nOldAntiAliase(mpOutputDevice->GetAntialiasing()); 446cdf0e10cSrcweir 447cdf0e10cSrcweir if(bForceLineSnap) 448cdf0e10cSrcweir { 449cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE); 450cdf0e10cSrcweir } 451cdf0e10cSrcweir 452cdf0e10cSrcweir // use new Metafile decomposition 453cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 454cdf0e10cSrcweir 455cdf0e10cSrcweir if(bForceLineSnap) 456cdf0e10cSrcweir { 457cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nOldAntiAliase); 458cdf0e10cSrcweir } 459cdf0e10cSrcweir 460cdf0e10cSrcweir break; 461cdf0e10cSrcweir } 462cdf0e10cSrcweir case PRIMITIVE2D_ID_MASKPRIMITIVE2D : 463cdf0e10cSrcweir { 464cdf0e10cSrcweir // mask group. 465cdf0e10cSrcweir RenderMaskPrimitive2DPixel(static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate)); 466cdf0e10cSrcweir break; 467cdf0e10cSrcweir } 468cdf0e10cSrcweir case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D : 469cdf0e10cSrcweir { 470cdf0e10cSrcweir // modified color group. Force output to unified color. 471cdf0e10cSrcweir RenderModifiedColorPrimitive2D(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate)); 472cdf0e10cSrcweir break; 473cdf0e10cSrcweir } 474cdf0e10cSrcweir case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D : 475cdf0e10cSrcweir { 476cdf0e10cSrcweir // Detect if a single PolyPolygonColorPrimitive2D is contained; in that case, 477cdf0e10cSrcweir // use the faster OutputDevice::DrawTransparent method 478cdf0e10cSrcweir const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate); 479cdf0e10cSrcweir const primitive2d::Primitive2DSequence rContent = rUniTransparenceCandidate.getChildren(); 480cdf0e10cSrcweir 481cdf0e10cSrcweir if(rContent.hasElements()) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir if(0.0 == rUniTransparenceCandidate.getTransparence()) 484cdf0e10cSrcweir { 485cdf0e10cSrcweir // not transparent at all, use content 486cdf0e10cSrcweir process(rUniTransparenceCandidate.getChildren()); 487cdf0e10cSrcweir } 488cdf0e10cSrcweir else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0) 489cdf0e10cSrcweir { 490cdf0e10cSrcweir bool bDrawTransparentUsed(false); 491cdf0e10cSrcweir 492cdf0e10cSrcweir // since DEV300 m33 DrawTransparent is supported in VCL (for some targets 493*922709c9Smseidel // natively), so I am now enabling this shortcut 494cdf0e10cSrcweir static bool bAllowUsingDrawTransparent(true); 495cdf0e10cSrcweir 496cdf0e10cSrcweir if(bAllowUsingDrawTransparent && 1 == rContent.getLength()) 497cdf0e10cSrcweir { 498cdf0e10cSrcweir const primitive2d::Primitive2DReference xReference(rContent[0]); 499cdf0e10cSrcweir const primitive2d::BasePrimitive2D* pBasePrimitive = dynamic_cast< const primitive2d::BasePrimitive2D* >(xReference.get()); 500cdf0e10cSrcweir 501cdf0e10cSrcweir if(pBasePrimitive) 502cdf0e10cSrcweir { 503cdf0e10cSrcweir switch(pBasePrimitive->getPrimitive2DID()) 504cdf0e10cSrcweir { 505cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D: 506cdf0e10cSrcweir { 507cdf0e10cSrcweir // single transparent PolyPolygon identified, use directly 508cdf0e10cSrcweir const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive); 509cdf0e10cSrcweir OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 5100f1c4fd1SArmin Le Grand bDrawTransparentUsed = tryDrawPolyPolygonColorPrimitive2DDirect(*pPoPoColor, rUniTransparenceCandidate.getTransparence()); 511cdf0e10cSrcweir break; 512cdf0e10cSrcweir } 5130f1c4fd1SArmin Le Grand case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D: 5140f1c4fd1SArmin Le Grand { 5150f1c4fd1SArmin Le Grand // single transparent PolygonHairlinePrimitive2D identified, use directly 5160f1c4fd1SArmin Le Grand const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive); 5170f1c4fd1SArmin Le Grand OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 5180f1c4fd1SArmin Le Grand 5190f1c4fd1SArmin Le Grand // do no tallow by default - problem is that self-overlapping parts of this geometry will 5200f1c4fd1SArmin Le Grand // not be in a all-same transparency but will already alpha-cover themselves with blending. 5210f1c4fd1SArmin Le Grand // This is not what the UnifiedTransparencePrimitive2D defines: It requires all it's 522*922709c9Smseidel // content to be uniformly transparent. 5230f1c4fd1SArmin Le Grand // For hairline the effect is pretty minimal, but still not correct. 5240f1c4fd1SArmin Le Grand static bool bAllowed(false); 5250f1c4fd1SArmin Le Grand 5260f1c4fd1SArmin Le Grand bDrawTransparentUsed = bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(*pPoHair, rUniTransparenceCandidate.getTransparence()); 5270f1c4fd1SArmin Le Grand break; 5280f1c4fd1SArmin Le Grand } 5290f1c4fd1SArmin Le Grand case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D: 5300f1c4fd1SArmin Le Grand { 5310f1c4fd1SArmin Le Grand // single transparent PolygonStrokePrimitive2D identified, use directly 5320f1c4fd1SArmin Le Grand const primitive2d::PolygonStrokePrimitive2D* pPoStroke = static_cast< const primitive2d::PolygonStrokePrimitive2D* >(pBasePrimitive); 5330f1c4fd1SArmin Le Grand OSL_ENSURE(pPoStroke, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 5340f1c4fd1SArmin Le Grand 5350f1c4fd1SArmin Le Grand // do no tallow by default - problem is that self-overlapping parts of this geometry will 5360f1c4fd1SArmin Le Grand // not be in a all-same transparency but will already alpha-cover themselves with blending. 5370f1c4fd1SArmin Le Grand // This is not what the UnifiedTransparencePrimitive2D defines: It requires all it's 538*922709c9Smseidel // content to be uniformly transparent. 539*922709c9Smseidel // To check, activate and draw a wide transparent self-crossing line/curve 5400f1c4fd1SArmin Le Grand static bool bAllowed(false); 5410f1c4fd1SArmin Le Grand 5420f1c4fd1SArmin Le Grand bDrawTransparentUsed = bAllowed && tryDrawPolygonStrokePrimitive2DDirect(*pPoStroke, rUniTransparenceCandidate.getTransparence()); 5430f1c4fd1SArmin Le Grand break; 5440f1c4fd1SArmin Le Grand } 545cdf0e10cSrcweir } 546cdf0e10cSrcweir } 547cdf0e10cSrcweir } 548cdf0e10cSrcweir 549cdf0e10cSrcweir if(!bDrawTransparentUsed) 550cdf0e10cSrcweir { 551cdf0e10cSrcweir // unified sub-transparence. Draw to VDev first. 552cdf0e10cSrcweir RenderUnifiedTransparencePrimitive2D(rUniTransparenceCandidate); 553cdf0e10cSrcweir } 554cdf0e10cSrcweir } 555cdf0e10cSrcweir } 556cdf0e10cSrcweir 557cdf0e10cSrcweir break; 558cdf0e10cSrcweir } 559cdf0e10cSrcweir case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D : 560cdf0e10cSrcweir { 561cdf0e10cSrcweir // sub-transparence group. Draw to VDev first. 562cdf0e10cSrcweir RenderTransparencePrimitive2D(static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate)); 563cdf0e10cSrcweir break; 564cdf0e10cSrcweir } 565cdf0e10cSrcweir case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D : 566cdf0e10cSrcweir { 567cdf0e10cSrcweir // transform group. 568cdf0e10cSrcweir RenderTransformPrimitive2D(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate)); 569cdf0e10cSrcweir break; 570cdf0e10cSrcweir } 571cdf0e10cSrcweir case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D : 572cdf0e10cSrcweir { 573cdf0e10cSrcweir // new XDrawPage for ViewInformation2D 574cdf0e10cSrcweir RenderPagePreviewPrimitive2D(static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate)); 575cdf0e10cSrcweir break; 576cdf0e10cSrcweir } 577cdf0e10cSrcweir case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D : 578cdf0e10cSrcweir { 579cdf0e10cSrcweir // marker array 580cdf0e10cSrcweir RenderMarkerArrayPrimitive2D(static_cast< const primitive2d::MarkerArrayPrimitive2D& >(rCandidate)); 581cdf0e10cSrcweir break; 582cdf0e10cSrcweir } 583cdf0e10cSrcweir case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D : 584cdf0e10cSrcweir { 585cdf0e10cSrcweir // point array 586cdf0e10cSrcweir RenderPointArrayPrimitive2D(static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate)); 587cdf0e10cSrcweir break; 588cdf0e10cSrcweir } 589cdf0e10cSrcweir case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D : 590cdf0e10cSrcweir { 591cdf0e10cSrcweir // control primitive 592cdf0e10cSrcweir const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate); 593cdf0e10cSrcweir const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl()); 594cdf0e10cSrcweir 595cdf0e10cSrcweir try 596cdf0e10cSrcweir { 597cdf0e10cSrcweir // remember old graphics and create new 598cdf0e10cSrcweir uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW); 599cdf0e10cSrcweir const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics()); 600cdf0e10cSrcweir const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics()); 601cdf0e10cSrcweir 602cdf0e10cSrcweir if(xNewGraphics.is()) 603cdf0e10cSrcweir { 604cdf0e10cSrcweir // link graphics and view 605cdf0e10cSrcweir xControlView->setGraphics(xNewGraphics); 606cdf0e10cSrcweir 607cdf0e10cSrcweir // get position 608cdf0e10cSrcweir const basegfx::B2DHomMatrix aObjectToPixel(maCurrentTransformation * rControlPrimitive.getTransform()); 609cdf0e10cSrcweir const basegfx::B2DPoint aTopLeftPixel(aObjectToPixel * basegfx::B2DPoint(0.0, 0.0)); 610cdf0e10cSrcweir 611cdf0e10cSrcweir // find out if the control is already visualized as a VCL-ChildWindow. If yes, 612cdf0e10cSrcweir // it does not need to be painted at all. 613cdf0e10cSrcweir uno::Reference< awt::XWindow2 > xControlWindow(rXControl, uno::UNO_QUERY_THROW); 614cdf0e10cSrcweir const bool bControlIsVisibleAsChildWindow(rXControl->getPeer().is() && xControlWindow->isVisible()); 615cdf0e10cSrcweir 616cdf0e10cSrcweir if(!bControlIsVisibleAsChildWindow) 617cdf0e10cSrcweir { 618cdf0e10cSrcweir // draw it. Do not forget to use the evtl. offsetted origin of the target device, 619cdf0e10cSrcweir // e.g. when used with mask/transparence buffer device 620cdf0e10cSrcweir const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin()); 621cdf0e10cSrcweir xControlView->draw( 622cdf0e10cSrcweir aOrigin.X() + basegfx::fround(aTopLeftPixel.getX()), 623cdf0e10cSrcweir aOrigin.Y() + basegfx::fround(aTopLeftPixel.getY())); 624cdf0e10cSrcweir } 625cdf0e10cSrcweir 626cdf0e10cSrcweir // restore original graphics 627cdf0e10cSrcweir xControlView->setGraphics(xOriginalGraphics); 628cdf0e10cSrcweir } 629cdf0e10cSrcweir } 630cdf0e10cSrcweir catch(const uno::Exception&) 631cdf0e10cSrcweir { 632cdf0e10cSrcweir // #i116763# removing since there is a good alternative when the xControlView 633cdf0e10cSrcweir // is not found and it is allowed to happen 634cdf0e10cSrcweir // DBG_UNHANDLED_EXCEPTION(); 635cdf0e10cSrcweir 636cdf0e10cSrcweir // process recursively and use the decomposition as Bitmap 637cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 638cdf0e10cSrcweir } 639cdf0e10cSrcweir 640cdf0e10cSrcweir break; 641cdf0e10cSrcweir } 642cdf0e10cSrcweir case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D: 643cdf0e10cSrcweir { 6440f1c4fd1SArmin Le Grand // try to use directly 6450f1c4fd1SArmin Le Grand const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive2D = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate); 6460f1c4fd1SArmin Le Grand 6470f1c4fd1SArmin Le Grand if(tryDrawPolygonStrokePrimitive2DDirect(rPolygonStrokePrimitive2D, 0.0)) 6480f1c4fd1SArmin Le Grand { 6490f1c4fd1SArmin Le Grand break; 6500f1c4fd1SArmin Le Grand } 6510f1c4fd1SArmin Le Grand 652cdf0e10cSrcweir // the stroke primitive may be decomposed to filled polygons. To keep 653cdf0e10cSrcweir // evtl. set DrawModes aka DRAWMODE_BLACKLINE, DRAWMODE_GRAYLINE, 654cdf0e10cSrcweir // DRAWMODE_GHOSTEDLINE, DRAWMODE_WHITELINE or DRAWMODE_SETTINGSLINE 655cdf0e10cSrcweir // working, these need to be copied to the corresponding fill modes 656cdf0e10cSrcweir const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 657cdf0e10cSrcweir adaptLineToFillDrawMode(); 658cdf0e10cSrcweir 659cdf0e10cSrcweir // polygon stroke primitive 660cdf0e10cSrcweir static bool bSuppressFatToHairlineCorrection(false); 661cdf0e10cSrcweir 662cdf0e10cSrcweir if(bSuppressFatToHairlineCorrection) 663cdf0e10cSrcweir { 66407a3d7f1SPedro Giffuni // remember that we enter a PolygonStrokePrimitive2D decomposition, 665cdf0e10cSrcweir // used for AA thick line drawing 666cdf0e10cSrcweir mnPolygonStrokePrimitive2D++; 667cdf0e10cSrcweir 668cdf0e10cSrcweir // with AA there is no need to handle thin lines special 669cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 670cdf0e10cSrcweir 671cdf0e10cSrcweir // leave PolygonStrokePrimitive2D 672cdf0e10cSrcweir mnPolygonStrokePrimitive2D--; 673cdf0e10cSrcweir } 674cdf0e10cSrcweir else 675cdf0e10cSrcweir { 676*922709c9Smseidel // Lines with 1 and 2 pixel width without AA need special treatment since their visualization 677*922709c9Smseidel // as filled polygons is geometrically correct but looks wrong since polygon filling avoids 678cdf0e10cSrcweir // the right and bottom pixels. The used method evaluates that and takes the correct action, 679cdf0e10cSrcweir // including calling recursively with decomposition if line is wide enough 6800f1c4fd1SArmin Le Grand RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive2D); 681cdf0e10cSrcweir } 682cdf0e10cSrcweir 683cdf0e10cSrcweir // restore DrawMode 684cdf0e10cSrcweir mpOutputDevice->SetDrawMode(nOriginalDrawMode); 685cdf0e10cSrcweir 686cdf0e10cSrcweir break; 687cdf0e10cSrcweir } 688cdf0e10cSrcweir case PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D : 689cdf0e10cSrcweir { 690cdf0e10cSrcweir static bool bForceIgnoreHatchSmoothing(false); 691cdf0e10cSrcweir 692cdf0e10cSrcweir if(bForceIgnoreHatchSmoothing || getOptionsDrawinglayer().IsAntiAliasing()) 693cdf0e10cSrcweir { 694cdf0e10cSrcweir // if AA is used (or ignore smoothing is on), there is no need to smooth 695cdf0e10cSrcweir // hatch painting, use decomposition 696cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 697cdf0e10cSrcweir } 698cdf0e10cSrcweir else 699cdf0e10cSrcweir { 700cdf0e10cSrcweir // without AA, use VCL to draw the hatch. It snaps hatch distances to the next pixel 701cdf0e10cSrcweir // and forces hatch distance to be >= 3 pixels to make the hatch display look smoother. 702cdf0e10cSrcweir // This is wrong in principle, but looks nicer. This could also be done here directly 703cdf0e10cSrcweir // without VCL usage if needed 704cdf0e10cSrcweir const primitive2d::FillHatchPrimitive2D& rFillHatchPrimitive = static_cast< const primitive2d::FillHatchPrimitive2D& >(rCandidate); 705cdf0e10cSrcweir const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch(); 706cdf0e10cSrcweir 707cdf0e10cSrcweir // create hatch polygon in range size and discrete coordinates 70864b14621SArmin Le Grand basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getOutputRange()); 709cdf0e10cSrcweir aHatchRange.transform(maCurrentTransformation); 710cdf0e10cSrcweir const basegfx::B2DPolygon aHatchPolygon(basegfx::tools::createPolygonFromRect(aHatchRange)); 711cdf0e10cSrcweir 712cdf0e10cSrcweir if(rFillHatchAttributes.isFillBackground()) 713cdf0e10cSrcweir { 714cdf0e10cSrcweir // #i111846# background fill is active; draw fill polygon 715cdf0e10cSrcweir const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor())); 716cdf0e10cSrcweir 717cdf0e10cSrcweir mpOutputDevice->SetFillColor(Color(aPolygonColor)); 718cdf0e10cSrcweir mpOutputDevice->SetLineColor(); 719cdf0e10cSrcweir mpOutputDevice->DrawPolygon(aHatchPolygon); 720cdf0e10cSrcweir } 721cdf0e10cSrcweir 722cdf0e10cSrcweir // set hatch line color 723cdf0e10cSrcweir const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor())); 724cdf0e10cSrcweir mpOutputDevice->SetFillColor(); 725cdf0e10cSrcweir mpOutputDevice->SetLineColor(Color(aHatchColor)); 726cdf0e10cSrcweir 727cdf0e10cSrcweir // get hatch style 728cdf0e10cSrcweir HatchStyle eHatchStyle(HATCH_SINGLE); 729cdf0e10cSrcweir 730cdf0e10cSrcweir switch(rFillHatchAttributes.getStyle()) 731cdf0e10cSrcweir { 732cdf0e10cSrcweir default : // HATCHSTYLE_SINGLE 733cdf0e10cSrcweir { 734cdf0e10cSrcweir break; 735cdf0e10cSrcweir } 736cdf0e10cSrcweir case attribute::HATCHSTYLE_DOUBLE : 737cdf0e10cSrcweir { 738cdf0e10cSrcweir eHatchStyle = HATCH_DOUBLE; 739cdf0e10cSrcweir break; 740cdf0e10cSrcweir } 741cdf0e10cSrcweir case attribute::HATCHSTYLE_TRIPLE : 742cdf0e10cSrcweir { 743cdf0e10cSrcweir eHatchStyle = HATCH_TRIPLE; 744cdf0e10cSrcweir break; 745cdf0e10cSrcweir } 746cdf0e10cSrcweir } 747cdf0e10cSrcweir 748cdf0e10cSrcweir // create hatch 749cdf0e10cSrcweir const basegfx::B2DVector aDiscreteDistance(maCurrentTransformation * basegfx::B2DVector(rFillHatchAttributes.getDistance(), 0.0)); 750cdf0e10cSrcweir const sal_uInt32 nDistance(basegfx::fround(aDiscreteDistance.getLength())); 751cdf0e10cSrcweir const sal_uInt16 nAngle10((sal_uInt16)basegfx::fround(rFillHatchAttributes.getAngle() / F_PI1800)); 752cdf0e10cSrcweir ::Hatch aVCLHatch(eHatchStyle, Color(rFillHatchAttributes.getColor()), nDistance, nAngle10); 753cdf0e10cSrcweir 754cdf0e10cSrcweir // draw hatch using VCL 755cdf0e10cSrcweir mpOutputDevice->DrawHatch(PolyPolygon(Polygon(aHatchPolygon)), aVCLHatch); 756cdf0e10cSrcweir } 757cdf0e10cSrcweir break; 758cdf0e10cSrcweir } 759cdf0e10cSrcweir case PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D : 760cdf0e10cSrcweir { 761cdf0e10cSrcweir // #i98404# Handle directly, especially when AA is active 762cdf0e10cSrcweir const primitive2d::BackgroundColorPrimitive2D& rPrimitive = static_cast< const primitive2d::BackgroundColorPrimitive2D& >(rCandidate); 763cdf0e10cSrcweir const sal_uInt16 nOriginalAA(mpOutputDevice->GetAntialiasing()); 764cdf0e10cSrcweir 765cdf0e10cSrcweir // switch AA off in all cases 766cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 767cdf0e10cSrcweir 768cdf0e10cSrcweir // create color for fill 769cdf0e10cSrcweir const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor())); 770cdf0e10cSrcweir mpOutputDevice->SetFillColor(Color(aPolygonColor)); 771cdf0e10cSrcweir mpOutputDevice->SetLineColor(); 772cdf0e10cSrcweir 773cdf0e10cSrcweir // create rectangle for fill 774cdf0e10cSrcweir const basegfx::B2DRange& aViewport(getViewInformation2D().getDiscreteViewport()); 775cdf0e10cSrcweir const Rectangle aRectangle( 776cdf0e10cSrcweir (sal_Int32)floor(aViewport.getMinX()), (sal_Int32)floor(aViewport.getMinY()), 777cdf0e10cSrcweir (sal_Int32)ceil(aViewport.getMaxX()), (sal_Int32)ceil(aViewport.getMaxY())); 778cdf0e10cSrcweir mpOutputDevice->DrawRect(aRectangle); 779cdf0e10cSrcweir 780cdf0e10cSrcweir // restore AA setting 781cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nOriginalAA); 782cdf0e10cSrcweir break; 783cdf0e10cSrcweir } 784cdf0e10cSrcweir case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D : 785cdf0e10cSrcweir { 786cdf0e10cSrcweir // #i97628# 787cdf0e10cSrcweir // This primitive means that the content is derived from an active text edit, 788cdf0e10cSrcweir // not from model data itself. Some renderers need to suppress this content, e.g. 789cdf0e10cSrcweir // the pixel renderer used for displaying the edit view (like this one). It's 790cdf0e10cSrcweir // not to be suppressed by the MetaFile renderers, so that the edited text is 791cdf0e10cSrcweir // part of the MetaFile, e.g. needed for presentation previews. 792cdf0e10cSrcweir // Action: Ignore here, do nothing. 793cdf0e10cSrcweir break; 794cdf0e10cSrcweir } 795cdf0e10cSrcweir case PRIMITIVE2D_ID_INVERTPRIMITIVE2D : 796cdf0e10cSrcweir { 797cdf0e10cSrcweir // invert primitive (currently only used for HighContrast fallback for selection in SW and SC). 798cdf0e10cSrcweir // Set OutDev to XOR and switch AA off (XOR does not work with AA) 799cdf0e10cSrcweir mpOutputDevice->Push(); 800cdf0e10cSrcweir mpOutputDevice->SetRasterOp( ROP_XOR ); 801cdf0e10cSrcweir const sal_uInt16 nAntiAliasing(mpOutputDevice->GetAntialiasing()); 802cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nAntiAliasing & ~ANTIALIASING_ENABLE_B2DDRAW); 803cdf0e10cSrcweir 804cdf0e10cSrcweir // process content recursively 805cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 806cdf0e10cSrcweir 807cdf0e10cSrcweir // restore OutDev 808cdf0e10cSrcweir mpOutputDevice->Pop(); 809cdf0e10cSrcweir mpOutputDevice->SetAntialiasing(nAntiAliasing); 810cdf0e10cSrcweir break; 811cdf0e10cSrcweir } 812cdf0e10cSrcweir case PRIMITIVE2D_ID_EPSPRIMITIVE2D : 813cdf0e10cSrcweir { 814cdf0e10cSrcweir RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); 815cdf0e10cSrcweir break; 816cdf0e10cSrcweir } 81739551d71SArmin Le Grand case PRIMITIVE2D_ID_SVGLINEARATOMPRIMITIVE2D: 81839551d71SArmin Le Grand { 81939551d71SArmin Le Grand RenderSvgLinearAtomPrimitive2D(static_cast< const primitive2d::SvgLinearAtomPrimitive2D& >(rCandidate)); 82039551d71SArmin Le Grand break; 82139551d71SArmin Le Grand } 82239551d71SArmin Le Grand case PRIMITIVE2D_ID_SVGRADIALATOMPRIMITIVE2D: 82339551d71SArmin Le Grand { 82439551d71SArmin Le Grand RenderSvgRadialAtomPrimitive2D(static_cast< const primitive2d::SvgRadialAtomPrimitive2D& >(rCandidate)); 82539551d71SArmin Le Grand break; 82639551d71SArmin Le Grand } 827cdf0e10cSrcweir default : 828cdf0e10cSrcweir { 829cdf0e10cSrcweir // process recursively 830cdf0e10cSrcweir process(rCandidate.get2DDecomposition(getViewInformation2D())); 831cdf0e10cSrcweir break; 832cdf0e10cSrcweir } 833cdf0e10cSrcweir } 834cdf0e10cSrcweir } 835cdf0e10cSrcweir } // end of namespace processor2d 836cdf0e10cSrcweir } // end of namespace drawinglayer 837cdf0e10cSrcweir 838*922709c9Smseidel /* vim: set noet sw=4 ts=4: */ 839