summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/outdev.hxx3
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/source/gdi/outdev/bezier.cxx40
-rw-r--r--vcl/source/gdi/outdev/outdev.cxx395
-rw-r--r--vcl/source/gdi/outdev/polygon.cxx381
5 files changed, 425 insertions, 395 deletions
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 3ca88fd1d8a6..0efbbcb05e31 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -253,6 +253,9 @@ typedef ::std::vector< VCLXGraphics* > VCLXGraphicsList_impl;
const char* ImplDbgCheckOutputDevice( const void* pObj );
+Polygon ImplSubdivideBezier( const Polygon& rPoly );
+PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly );
+
class VCL_DLLPUBLIC OutputDevice
{
friend class Application;
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index ba64644103df..14a097425e5e 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -234,6 +234,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/gdi/metric \
vcl/source/gdi/octree \
vcl/source/gdi/oldprintadaptor \
+ vcl/source/gdi/outdev/bezier \
vcl/source/gdi/outdev/polygon \
vcl/source/gdi/outdev/outdev2 \
vcl/source/gdi/outdev/outdev3 \
diff --git a/vcl/source/gdi/outdev/bezier.cxx b/vcl/source/gdi/outdev/bezier.cxx
new file mode 100644
index 000000000000..2736c4db43d8
--- /dev/null
+++ b/vcl/source/gdi/outdev/bezier.cxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/poly.hxx>
+
+Polygon ImplSubdivideBezier( const Polygon& rPoly )
+{
+ Polygon aPoly;
+
+ // #100127# Use adaptive subdivide instead of fixed 25 segments
+ rPoly.AdaptiveSubdivide( aPoly );
+
+ return aPoly;
+}
+
+PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly )
+{
+ sal_uInt16 i, nPolys = rPolyPoly.Count();
+ PolyPolygon aPolyPoly( nPolys );
+ for( i=0; i<nPolys; ++i )
+ aPolyPoly.Insert( ImplSubdivideBezier( rPolyPoly.GetObject(i) ) );
+
+ return aPolyPoly;
+}
diff --git a/vcl/source/gdi/outdev/outdev.cxx b/vcl/source/gdi/outdev/outdev.cxx
index 1b7830b7d813..a05dfa7dfdd3 100644
--- a/vcl/source/gdi/outdev/outdev.cxx
+++ b/vcl/source/gdi/outdev/outdev.cxx
@@ -90,8 +90,6 @@ const char* ImplDbgCheckOutputDevice( const void* pObj )
}
#endif
-#define OUTDEV_POLYPOLY_STACKBUF 32
-
struct ImplObjStack
{
ImplObjStack* mpPrev;
@@ -194,115 +192,6 @@ bool OutputDevice::ImplSelectClipRegion( const Region& rRegion, SalGraphics* pGr
return bClipRegion;
}
-Polygon ImplSubdivideBezier( const Polygon& rPoly )
-{
- Polygon aPoly;
-
- // #100127# Use adaptive subdivide instead of fixed 25 segments
- rPoly.AdaptiveSubdivide( aPoly );
-
- return aPoly;
-}
-
-PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly )
-{
- sal_uInt16 i, nPolys = rPolyPoly.Count();
- PolyPolygon aPolyPoly( nPolys );
- for( i=0; i<nPolys; ++i )
- aPolyPoly.Insert( ImplSubdivideBezier( rPolyPoly.GetObject(i) ) );
-
- return aPolyPoly;
-}
-
-// #100127# Extracted from OutputDevice::DrawPolyPolygon()
-void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPolyPoly )
-{
- // AW: This crashes on empty PolyPolygons, avoid that
- if(!nPoly)
- return;
-
- sal_uInt32 aStackAry1[OUTDEV_POLYPOLY_STACKBUF];
- PCONSTSALPOINT aStackAry2[OUTDEV_POLYPOLY_STACKBUF];
- sal_uInt8* aStackAry3[OUTDEV_POLYPOLY_STACKBUF];
- sal_uInt32* pPointAry;
- PCONSTSALPOINT* pPointAryAry;
- const sal_uInt8** pFlagAryAry;
- sal_uInt16 i = 0, j = 0, last = 0;
- bool bHaveBezier = false;
- if ( nPoly > OUTDEV_POLYPOLY_STACKBUF )
- {
- pPointAry = new sal_uInt32[nPoly];
- pPointAryAry = new PCONSTSALPOINT[nPoly];
- pFlagAryAry = new const sal_uInt8*[nPoly];
- }
- else
- {
- pPointAry = aStackAry1;
- pPointAryAry = aStackAry2;
- pFlagAryAry = (const sal_uInt8**)aStackAry3;
- }
- do
- {
- const Polygon& rPoly = rPolyPoly.GetObject( i );
- sal_uInt16 nSize = rPoly.GetSize();
- if ( nSize )
- {
- pPointAry[j] = nSize;
- pPointAryAry[j] = (PCONSTSALPOINT)rPoly.GetConstPointAry();
- pFlagAryAry[j] = rPoly.GetConstFlagAry();
- last = i;
-
- if( pFlagAryAry[j] )
- bHaveBezier = true;
-
- ++j;
- }
-
- ++i;
- }
- while ( i < nPoly );
-
- if ( j == 1 )
- {
- // #100127# Forward beziers to sal, if any
- if( bHaveBezier )
- {
- if( !mpGraphics->DrawPolygonBezier( *pPointAry, *pPointAryAry, *pFlagAryAry, this ) )
- {
- Polygon aPoly = ImplSubdivideBezier( rPolyPoly.GetObject( last ) );
- mpGraphics->DrawPolygon( aPoly.GetSize(), (const SalPoint*)aPoly.GetConstPointAry(), this );
- }
- }
- else
- {
- mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this );
- }
- }
- else
- {
- // #100127# Forward beziers to sal, if any
- if( bHaveBezier )
- {
- if( !mpGraphics->DrawPolyPolygonBezier( j, pPointAry, pPointAryAry, pFlagAryAry, this ) )
- {
- PolyPolygon aPolyPoly = ImplSubdivideBezier( rPolyPoly );
- ImplDrawPolyPolygon( aPolyPoly.Count(), aPolyPoly );
- }
- }
- else
- {
- mpGraphics->DrawPolyPolygon( j, pPointAry, pPointAryAry, this );
- }
- }
-
- if ( pPointAry != aStackAry1 )
- {
- delete[] pPointAry;
- delete[] pPointAryAry;
- delete[] pFlagAryAry;
- }
-}
-
OutputDevice::OutputDevice() :
maRegion(true),
maFillColor( COL_WHITE ),
@@ -1564,290 +1453,6 @@ void OutputDevice::ImplDrawPolyLineWithLineInfo(const Polygon& rPoly, const Line
mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo );
}
-void OutputDevice::DrawPolygon( const Polygon& rPoly )
-{
-
- if( mpMetaFile )
- mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
-
- sal_uInt16 nPoints = rPoly.GetSize();
-
- if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) || ImplIsRecordLayout() )
- return;
-
- // we need a graphics
- if ( !mpGraphics )
- if ( !ImplGetGraphics() )
- return;
-
- if ( mbInitClipRegion )
- ImplInitClipRegion();
- if ( mbOutputClipped )
- return;
-
- if ( mbInitLineColor )
- ImplInitLineColor();
- if ( mbInitFillColor )
- ImplInitFillColor();
-
- // use b2dpolygon drawing if possible
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
- && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
- && ROP_OVERPAINT == GetRasterOp()
- && (IsLineColor() || IsFillColor()))
- {
- const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon());
- bool bSuccess(true);
-
- // transform the polygon and ensure closed
- aB2DPolygon.transform(aTransform);
- aB2DPolygon.setClosed(true);
-
- if(IsFillColor())
- {
- bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this);
- }
-
- if(bSuccess && IsLineColor())
- {
- const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
-
- if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
- {
- aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
- }
-
- bSuccess = mpGraphics->DrawPolyLine(
- aB2DPolygon,
- 0.0,
- aB2DLineWidth,
- basegfx::B2DLINEJOIN_NONE,
- css::drawing::LineCap_BUTT,
- this);
- }
-
- if(bSuccess)
- {
- return;
- }
- }
-
- Polygon aPoly = ImplLogicToDevicePixel( rPoly );
- const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
-
- // #100127# Forward beziers to sal, if any
- if( aPoly.HasFlags() )
- {
- const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
- if( !mpGraphics->DrawPolygonBezier( nPoints, pPtAry, pFlgAry, this ) )
- {
- aPoly = ImplSubdivideBezier(aPoly);
- pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
- mpGraphics->DrawPolygon( aPoly.GetSize(), pPtAry, this );
- }
- }
- else
- {
- mpGraphics->DrawPolygon( nPoints, pPtAry, this );
- }
- if( mpAlphaVDev )
- mpAlphaVDev->DrawPolygon( rPoly );
-}
-
-void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
-{
-
- if( mpMetaFile )
- mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
-
- sal_uInt16 nPoly = rPolyPoly.Count();
-
- if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly || ImplIsRecordLayout() )
- return;
-
- // we need a graphics
- if ( !mpGraphics )
- if ( !ImplGetGraphics() )
- return;
-
- if ( mbInitClipRegion )
- ImplInitClipRegion();
- if ( mbOutputClipped )
- return;
-
- if ( mbInitLineColor )
- ImplInitLineColor();
- if ( mbInitFillColor )
- ImplInitFillColor();
-
- // use b2dpolygon drawing if possible
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
- && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
- && ROP_OVERPAINT == GetRasterOp()
- && (IsLineColor() || IsFillColor()))
- {
- const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon());
- bool bSuccess(true);
-
- // transform the polygon and ensure closed
- aB2DPolyPolygon.transform(aTransform);
- aB2DPolyPolygon.setClosed(true);
-
- if(IsFillColor())
- {
- bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
- }
-
- if(bSuccess && IsLineColor())
- {
- const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
-
- if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
- {
- aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
- }
-
- for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++)
- {
- bSuccess = mpGraphics->DrawPolyLine(
- aB2DPolyPolygon.getB2DPolygon(a),
- 0.0,
- aB2DLineWidth,
- basegfx::B2DLINEJOIN_NONE,
- css::drawing::LineCap_BUTT,
- this);
- }
- }
-
- if(bSuccess)
- {
- return;
- }
- }
-
- if ( nPoly == 1 )
- {
- // #100127# Map to DrawPolygon
- Polygon aPoly = rPolyPoly.GetObject( 0 );
- if( aPoly.GetSize() >= 2 )
- {
- GDIMetaFile* pOldMF = mpMetaFile;
- mpMetaFile = NULL;
-
- DrawPolygon( aPoly );
-
- mpMetaFile = pOldMF;
- }
- }
- else
- {
- // #100127# moved real PolyPolygon draw to separate method,
- // have to call recursively, avoiding duplicate
- // ImplLogicToDevicePixel calls
- ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) );
- }
- if( mpAlphaVDev )
- mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
-}
-
-void OutputDevice::DrawPolygon( const basegfx::B2DPolygon& rB2DPolygon)
-{
- // AW: Do NOT paint empty polygons
- if(rB2DPolygon.count())
- {
- basegfx::B2DPolyPolygon aPP( rB2DPolygon );
- DrawPolyPolygon( aPP );
- }
-}
-
-// Caution: This method is nearly the same as
-// OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency),
-// so when changes are made here do not forget to make change sthere, too
-
-void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
-{
-
- if( mpMetaFile )
- mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) );
-
- // call helper
- ImplDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
-}
-
-void OutputDevice::ImplDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly)
-{
- // Do not paint empty PolyPolygons
- if(!rB2DPolyPoly.count() || !IsDeviceOutputNecessary())
- return;
-
- // we need a graphics
- if( !mpGraphics )
- if( !ImplGetGraphics() )
- return;
-
- if( mbInitClipRegion )
- ImplInitClipRegion();
- if( mbOutputClipped )
- return;
-
- if( mbInitLineColor )
- ImplInitLineColor();
- if( mbInitFillColor )
- ImplInitFillColor();
-
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
- && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
- && ROP_OVERPAINT == GetRasterOp()
- && (IsLineColor() || IsFillColor()))
- {
- const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
- basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
- bool bSuccess(true);
-
- // transform the polygon and ensure closed
- aB2DPolyPolygon.transform(aTransform);
- aB2DPolyPolygon.setClosed(true);
-
- if(IsFillColor())
- {
- bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
- }
-
- if(bSuccess && IsLineColor())
- {
- const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
-
- if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
- {
- aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
- }
-
- for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++)
- {
- bSuccess = mpGraphics->DrawPolyLine(
- aB2DPolyPolygon.getB2DPolygon(a),
- 0.0,
- aB2DLineWidth,
- basegfx::B2DLINEJOIN_NONE,
- css::drawing::LineCap_BUTT,
- this);
- }
- }
-
- if(bSuccess)
- {
- return;
- }
- }
-
- // fallback to old polygon drawing if needed
- const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
- const PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel( aToolsPolyPolygon );
- ImplDrawPolyPolygon( aPixelPolyPolygon.Count(), aPixelPolyPolygon );
-}
-
bool OutputDevice::ImplTryDrawPolyLineDirect(
const basegfx::B2DPolygon& rB2DPolygon,
double fLineWidth,
diff --git a/vcl/source/gdi/outdev/polygon.cxx b/vcl/source/gdi/outdev/polygon.cxx
index 5ded92041f4f..91c6fa48b328 100644
--- a/vcl/source/gdi/outdev/polygon.cxx
+++ b/vcl/source/gdi/outdev/polygon.cxx
@@ -34,12 +34,393 @@
#include "svdata.hxx"
#include "outdata.hxx"
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/vector/b2dvector.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/polygon/b2dlinegeometry.hxx>
+
#include <boost/scoped_array.hpp>
#include <boost/scoped_ptr.hpp>
+#define OUTDEV_POLYPOLY_STACKBUF 32
+
+void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
+{
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
+
+ sal_uInt16 nPoly = rPolyPoly.Count();
+
+ if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly || ImplIsRecordLayout() )
+ return;
+
+ // we need a graphics
+ if ( !mpGraphics )
+ if ( !ImplGetGraphics() )
+ return;
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+
+ // use b2dpolygon drawing if possible
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && (IsLineColor() || IsFillColor()))
+ {
+ const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon());
+ bool bSuccess(true);
+
+ // transform the polygon and ensure closed
+ aB2DPolyPolygon.transform(aTransform);
+ aB2DPolyPolygon.setClosed(true);
+
+ if(IsFillColor())
+ {
+ bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
+ }
+
+ if(bSuccess && IsLineColor())
+ {
+ const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
+
+ if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
+ {
+ aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
+ }
+
+ for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++)
+ {
+ bSuccess = mpGraphics->DrawPolyLine(
+ aB2DPolyPolygon.getB2DPolygon(a),
+ 0.0,
+ aB2DLineWidth,
+ basegfx::B2DLINEJOIN_NONE,
+ css::drawing::LineCap_BUTT,
+ this);
+ }
+ }
+
+ if(bSuccess)
+ {
+ return;
+ }
+ }
+
+ if ( nPoly == 1 )
+ {
+ // #100127# Map to DrawPolygon
+ Polygon aPoly = rPolyPoly.GetObject( 0 );
+ if( aPoly.GetSize() >= 2 )
+ {
+ GDIMetaFile* pOldMF = mpMetaFile;
+ mpMetaFile = NULL;
+
+ DrawPolygon( aPoly );
+
+ mpMetaFile = pOldMF;
+ }
+ }
+ else
+ {
+ // #100127# moved real PolyPolygon draw to separate method,
+ // have to call recursively, avoiding duplicate
+ // ImplLogicToDevicePixel calls
+ ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) );
+ }
+ if( mpAlphaVDev )
+ mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
+}
+
+void OutputDevice::DrawPolygon( const basegfx::B2DPolygon& rB2DPolygon)
+{
+ // AW: Do NOT paint empty polygons
+ if(rB2DPolygon.count())
+ {
+ basegfx::B2DPolyPolygon aPP( rB2DPolygon );
+ DrawPolyPolygon( aPP );
+ }
+}
+
+void OutputDevice::DrawPolygon( const Polygon& rPoly )
+{
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
+
+ sal_uInt16 nPoints = rPoly.GetSize();
+
+ if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) || ImplIsRecordLayout() )
+ return;
+
+ // we need a graphics
+ if ( !mpGraphics )
+ if ( !ImplGetGraphics() )
+ return;
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+
+ // use b2dpolygon drawing if possible
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && (IsLineColor() || IsFillColor()))
+ {
+ const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
+ basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon());
+ bool bSuccess(true);
+
+ // transform the polygon and ensure closed
+ aB2DPolygon.transform(aTransform);
+ aB2DPolygon.setClosed(true);
+
+ if(IsFillColor())
+ {
+ bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this);
+ }
+
+ if(bSuccess && IsLineColor())
+ {
+ const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
+
+ if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
+ {
+ aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
+ }
+
+ bSuccess = mpGraphics->DrawPolyLine(
+ aB2DPolygon,
+ 0.0,
+ aB2DLineWidth,
+ basegfx::B2DLINEJOIN_NONE,
+ css::drawing::LineCap_BUTT,
+ this);
+ }
+
+ if(bSuccess)
+ {
+ return;
+ }
+ }
+
+ Polygon aPoly = ImplLogicToDevicePixel( rPoly );
+ const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
+
+ // #100127# Forward beziers to sal, if any
+ if( aPoly.HasFlags() )
+ {
+ const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
+ if( !mpGraphics->DrawPolygonBezier( nPoints, pPtAry, pFlgAry, this ) )
+ {
+ aPoly = ImplSubdivideBezier(aPoly);
+ pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
+ mpGraphics->DrawPolygon( aPoly.GetSize(), pPtAry, this );
+ }
+ }
+ else
+ {
+ mpGraphics->DrawPolygon( nPoints, pPtAry, this );
+ }
+ if( mpAlphaVDev )
+ mpAlphaVDev->DrawPolygon( rPoly );
+}
+
+// Caution: This method is nearly the same as
+// OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency),
+// so when changes are made here do not forget to make change sthere, too
+
+void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
+{
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) );
+
+ // call helper
+ ImplDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
+}
+
+void OutputDevice::ImplDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly)
+{
+ // Do not paint empty PolyPolygons
+ if(!rB2DPolyPoly.count() || !IsDeviceOutputNecessary())
+ return;
+
+ // we need a graphics
+ if( !mpGraphics )
+ if( !ImplGetGraphics() )
+ return;
+
+ if( mbInitClipRegion )
+ ImplInitClipRegion();
+ if( mbOutputClipped )
+ return;
+
+ if( mbInitLineColor )
+ ImplInitLineColor();
+ if( mbInitFillColor )
+ ImplInitFillColor();
+
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && (IsLineColor() || IsFillColor()))
+ {
+ const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
+ bool bSuccess(true);
+
+ // transform the polygon and ensure closed
+ aB2DPolyPolygon.transform(aTransform);
+ aB2DPolyPolygon.setClosed(true);
+
+ if(IsFillColor())
+ {
+ bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
+ }
+
+ if(bSuccess && IsLineColor())
+ {
+ const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
+
+ if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
+ {
+ aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
+ }
+
+ for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++)
+ {
+ bSuccess = mpGraphics->DrawPolyLine(
+ aB2DPolyPolygon.getB2DPolygon(a),
+ 0.0,
+ aB2DLineWidth,
+ basegfx::B2DLINEJOIN_NONE,
+ css::drawing::LineCap_BUTT,
+ this);
+ }
+ }
+
+ if(bSuccess)
+ {
+ return;
+ }
+ }
+
+ // fallback to old polygon drawing if needed
+ const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
+ const PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel( aToolsPolyPolygon );
+ ImplDrawPolyPolygon( aPixelPolyPolygon.Count(), aPixelPolyPolygon );
+}
+
+// #100127# Extracted from OutputDevice::DrawPolyPolygon()
+void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPolyPoly )
+{
+ // AW: This crashes on empty PolyPolygons, avoid that
+ if(!nPoly)
+ return;
+
+ sal_uInt32 aStackAry1[OUTDEV_POLYPOLY_STACKBUF];
+ PCONSTSALPOINT aStackAry2[OUTDEV_POLYPOLY_STACKBUF];
+ sal_uInt8* aStackAry3[OUTDEV_POLYPOLY_STACKBUF];
+ sal_uInt32* pPointAry;
+ PCONSTSALPOINT* pPointAryAry;
+ const sal_uInt8** pFlagAryAry;
+ sal_uInt16 i = 0, j = 0, last = 0;
+ bool bHaveBezier = false;
+ if ( nPoly > OUTDEV_POLYPOLY_STACKBUF )
+ {
+ pPointAry = new sal_uInt32[nPoly];
+ pPointAryAry = new PCONSTSALPOINT[nPoly];
+ pFlagAryAry = new const sal_uInt8*[nPoly];
+ }
+ else
+ {
+ pPointAry = aStackAry1;
+ pPointAryAry = aStackAry2;
+ pFlagAryAry = (const sal_uInt8**)aStackAry3;
+ }
+ do
+ {
+ const Polygon& rPoly = rPolyPoly.GetObject( i );
+ sal_uInt16 nSize = rPoly.GetSize();
+ if ( nSize )
+ {
+ pPointAry[j] = nSize;
+ pPointAryAry[j] = (PCONSTSALPOINT)rPoly.GetConstPointAry();
+ pFlagAryAry[j] = rPoly.GetConstFlagAry();
+ last = i;
+
+ if( pFlagAryAry[j] )
+ bHaveBezier = true;
+
+ ++j;
+ }
+
+ ++i;
+ }
+ while ( i < nPoly );
+
+ if ( j == 1 )
+ {
+ // #100127# Forward beziers to sal, if any
+ if( bHaveBezier )
+ {
+ if( !mpGraphics->DrawPolygonBezier( *pPointAry, *pPointAryAry, *pFlagAryAry, this ) )
+ {
+ Polygon aPoly = ImplSubdivideBezier( rPolyPoly.GetObject( last ) );
+ mpGraphics->DrawPolygon( aPoly.GetSize(), (const SalPoint*)aPoly.GetConstPointAry(), this );
+ }
+ }
+ else
+ {
+ mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this );
+ }
+ }
+ else
+ {
+ // #100127# Forward beziers to sal, if any
+ if( bHaveBezier )
+ {
+ if( !mpGraphics->DrawPolyPolygonBezier( j, pPointAry, pPointAryAry, pFlagAryAry, this ) )
+ {
+ PolyPolygon aPolyPoly = ImplSubdivideBezier( rPolyPoly );
+ ImplDrawPolyPolygon( aPolyPoly.Count(), aPolyPoly );
+ }
+ }
+ else
+ {
+ mpGraphics->DrawPolyPolygon( j, pPointAry, pPointAryAry, this );
+ }
+ }
+
+ if ( pPointAry != aStackAry1 )
+ {
+ delete[] pPointAry;
+ delete[] pPointAryAry;
+ delete[] pFlagAryAry;
+ }
+}
+
void OutputDevice::ImplDrawPolygon( const Polygon& rPoly, const PolyPolygon* pClipPolyPoly )
{
if( pClipPolyPoly )