Resolves: #i110384# added better fat line rendering where possible
(cherry picked from commit 144eb666b72516ef78c15424087800dff1be5cfd) Conflicts: drawinglayer/inc/drawinglayer/processor2d/vclpixelprocessor2d.hxx drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx vcl/inc/vcl/outdev.hxx Change-Id: I89f378a4d7a8311b8922f10acff66b000a20a4b7
This commit is contained in:
committed by
Caolán McNamara
parent
5e5f3671f8
commit
02da9f7a91
@@ -92,6 +92,141 @@ namespace drawinglayer
|
|||||||
mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
|
mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VclPixelProcessor2D::tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D& rSource, double fTransparency)
|
||||||
|
{
|
||||||
|
basegfx::B2DPolyPolygon aLocalPolyPolygon(rSource.getB2DPolyPolygon());
|
||||||
|
|
||||||
|
if(!aLocalPolyPolygon.count())
|
||||||
|
{
|
||||||
|
// no geometry, done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rSource.getBColor()));
|
||||||
|
|
||||||
|
mpOutputDevice->SetFillColor(Color(aPolygonColor));
|
||||||
|
mpOutputDevice->SetLineColor();
|
||||||
|
aLocalPolyPolygon.transform(maCurrentTransformation);
|
||||||
|
mpOutputDevice->DrawTransparent(
|
||||||
|
aLocalPolyPolygon,
|
||||||
|
fTransparency);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VclPixelProcessor2D::tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D& rSource, double fTransparency)
|
||||||
|
{
|
||||||
|
basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon());
|
||||||
|
|
||||||
|
if(!aLocalPolygon.count())
|
||||||
|
{
|
||||||
|
// no geometry, done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const basegfx::BColor aLineColor(maBColorModifierStack.getModifiedColor(rSource.getBColor()));
|
||||||
|
|
||||||
|
mpOutputDevice->SetFillColor();
|
||||||
|
mpOutputDevice->SetLineColor(Color(aLineColor));
|
||||||
|
aLocalPolygon.transform(maCurrentTransformation);
|
||||||
|
|
||||||
|
// try drawing; if it did not work, use standard fallback
|
||||||
|
if(mpOutputDevice->TryDrawPolyLineDirect(
|
||||||
|
aLocalPolygon,
|
||||||
|
0.0,
|
||||||
|
fTransparency))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D& rSource, double fTransparency)
|
||||||
|
{
|
||||||
|
basegfx::B2DPolygon aLocalPolygon(rSource.getB2DPolygon());
|
||||||
|
|
||||||
|
if(!aLocalPolygon.count())
|
||||||
|
{
|
||||||
|
// no geometry, done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
aLocalPolygon = basegfx::tools::simplifyCurveSegments(aLocalPolygon);
|
||||||
|
basegfx::B2DPolyPolygon aHairLinePolyPolygon;
|
||||||
|
|
||||||
|
if(rSource.getStrokeAttribute().isDefault() || 0.0 == rSource.getStrokeAttribute().getFullDotDashLen())
|
||||||
|
{
|
||||||
|
// no line dashing, just copy
|
||||||
|
aHairLinePolyPolygon.append(aLocalPolygon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// apply LineStyle
|
||||||
|
basegfx::tools::applyLineDashing(
|
||||||
|
aLocalPolygon,
|
||||||
|
rSource.getStrokeAttribute().getDotDashArray(),
|
||||||
|
&aHairLinePolyPolygon,
|
||||||
|
0,
|
||||||
|
rSource.getStrokeAttribute().getFullDotDashLen());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!aHairLinePolyPolygon.count())
|
||||||
|
{
|
||||||
|
// no geometry, done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const basegfx::BColor aLineColor(
|
||||||
|
maBColorModifierStack.getModifiedColor(
|
||||||
|
rSource.getLineAttribute().getColor()));
|
||||||
|
|
||||||
|
mpOutputDevice->SetFillColor();
|
||||||
|
mpOutputDevice->SetLineColor(Color(aLineColor));
|
||||||
|
aHairLinePolyPolygon.transform(maCurrentTransformation);
|
||||||
|
|
||||||
|
double fLineWidth(rSource.getLineAttribute().getWidth());
|
||||||
|
|
||||||
|
if(basegfx::fTools::more(fLineWidth, 0.0))
|
||||||
|
{
|
||||||
|
basegfx::B2DVector aLineWidth(fLineWidth, 0.0);
|
||||||
|
|
||||||
|
aLineWidth = maCurrentTransformation * aLineWidth;
|
||||||
|
fLineWidth = aLineWidth.getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bHasPoints(false);
|
||||||
|
bool bTryWorked(false);
|
||||||
|
|
||||||
|
for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++)
|
||||||
|
{
|
||||||
|
const basegfx::B2DPolygon aSingle(aHairLinePolyPolygon.getB2DPolygon(a));
|
||||||
|
|
||||||
|
if(aSingle.count())
|
||||||
|
{
|
||||||
|
bHasPoints = true;
|
||||||
|
|
||||||
|
if(mpOutputDevice->TryDrawPolyLineDirect(
|
||||||
|
aSingle,
|
||||||
|
fLineWidth,
|
||||||
|
fTransparency,
|
||||||
|
rSource.getLineAttribute().getLineJoin(),
|
||||||
|
rSource.getLineAttribute().getLineCap()))
|
||||||
|
{
|
||||||
|
bTryWorked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!bTryWorked && !bHasPoints)
|
||||||
|
{
|
||||||
|
// no geometry despite try
|
||||||
|
bTryWorked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bTryWorked;
|
||||||
|
}
|
||||||
|
|
||||||
void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
|
void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
|
||||||
{
|
{
|
||||||
switch(rCandidate.getPrimitive2DID())
|
switch(rCandidate.getPrimitive2DID())
|
||||||
@@ -169,8 +304,17 @@ namespace drawinglayer
|
|||||||
}
|
}
|
||||||
case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D :
|
case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D :
|
||||||
{
|
{
|
||||||
|
// try to use directly
|
||||||
|
const primitive2d::PolygonHairlinePrimitive2D& rPolygonHairlinePrimitive2D = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate);
|
||||||
|
static bool bAllowed(true);
|
||||||
|
|
||||||
|
if(bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(rPolygonHairlinePrimitive2D, 0.0))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// direct draw of hairline
|
// direct draw of hairline
|
||||||
RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), true);
|
RenderPolygonHairlinePrimitive2D(rPolygonHairlinePrimitive2D, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
|
case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
|
||||||
@@ -240,8 +384,53 @@ namespace drawinglayer
|
|||||||
}
|
}
|
||||||
case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
|
case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
|
||||||
{
|
{
|
||||||
// direct draw of PolyPolygon with color
|
// try to use directly
|
||||||
RenderPolyPolygonColorPrimitive2D(static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate));
|
const primitive2d::PolyPolygonColorPrimitive2D& rPolyPolygonColorPrimitive2D = static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate);
|
||||||
|
basegfx::B2DPolyPolygon aLocalPolyPolygon;
|
||||||
|
static bool bAllowed(true);
|
||||||
|
|
||||||
|
if(bAllowed && tryDrawPolyPolygonColorPrimitive2DDirect(rPolyPolygonColorPrimitive2D, 0.0))
|
||||||
|
{
|
||||||
|
// okay, done. In this case no gaps should have to be repaired, too
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// direct draw of PolyPolygon with color
|
||||||
|
const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));
|
||||||
|
|
||||||
|
mpOutputDevice->SetFillColor(Color(aPolygonColor));
|
||||||
|
mpOutputDevice->SetLineColor();
|
||||||
|
aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon();
|
||||||
|
aLocalPolyPolygon.transform(maCurrentTransformation);
|
||||||
|
mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// when AA is on and this filled polygons are the result of stroked line geometry,
|
||||||
|
// draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons
|
||||||
|
// Caution: This is needed in both cases (!)
|
||||||
|
if(mnPolygonStrokePrimitive2D
|
||||||
|
&& getOptionsDrawinglayer().IsAntiAliasing()
|
||||||
|
&& (mpOutputDevice->GetAntialiasing() & ANTIALIASING_ENABLE_B2DDRAW))
|
||||||
|
{
|
||||||
|
const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));
|
||||||
|
sal_uInt32 nCount(aLocalPolyPolygon.count());
|
||||||
|
|
||||||
|
if(!nCount)
|
||||||
|
{
|
||||||
|
aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon();
|
||||||
|
aLocalPolyPolygon.transform(maCurrentTransformation);
|
||||||
|
nCount = aLocalPolyPolygon.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
mpOutputDevice->SetFillColor();
|
||||||
|
mpOutputDevice->SetLineColor(Color(aPolygonColor));
|
||||||
|
|
||||||
|
for(sal_uInt32 a(0); a < nCount; a++)
|
||||||
|
{
|
||||||
|
mpOutputDevice->DrawPolyLine(aLocalPolyPolygon.getB2DPolygon(a), 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
|
case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
|
||||||
@@ -313,25 +502,41 @@ namespace drawinglayer
|
|||||||
// single transparent PolyPolygon identified, use directly
|
// single transparent PolyPolygon identified, use directly
|
||||||
const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive);
|
const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive);
|
||||||
OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)");
|
OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)");
|
||||||
const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor()));
|
bDrawTransparentUsed = tryDrawPolyPolygonColorPrimitive2DDirect(*pPoPoColor, rUniTransparenceCandidate.getTransparence());
|
||||||
mpOutputDevice->SetFillColor(Color(aPolygonColor));
|
break;
|
||||||
mpOutputDevice->SetLineColor();
|
}
|
||||||
|
case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D:
|
||||||
basegfx::B2DPolyPolygon aLocalPolyPolygon(pPoPoColor->getB2DPolyPolygon());
|
{
|
||||||
aLocalPolyPolygon.transform(maCurrentTransformation);
|
// single transparent PolygonHairlinePrimitive2D identified, use directly
|
||||||
|
const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive);
|
||||||
mpOutputDevice->DrawTransparent(aLocalPolyPolygon, rUniTransparenceCandidate.getTransparence());
|
OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)");
|
||||||
bDrawTransparentUsed = true;
|
|
||||||
|
// do no tallow by default - problem is that self-overlapping parts of this geometry will
|
||||||
|
// not be in a all-same transparency but will already alpha-cover themselves with blending.
|
||||||
|
// This is not what the UnifiedTransparencePrimitive2D defines: It requires all it's
|
||||||
|
// content to be uniformely transparent.
|
||||||
|
// For hairline the effect is pretty minimal, but still not correct.
|
||||||
|
static bool bAllowed(false);
|
||||||
|
|
||||||
|
bDrawTransparentUsed = bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(*pPoHair, rUniTransparenceCandidate.getTransparence());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
|
||||||
|
{
|
||||||
|
// single transparent PolygonStrokePrimitive2D identified, use directly
|
||||||
|
const primitive2d::PolygonStrokePrimitive2D* pPoStroke = static_cast< const primitive2d::PolygonStrokePrimitive2D* >(pBasePrimitive);
|
||||||
|
OSL_ENSURE(pPoStroke, "OOps, PrimitiveID and PrimitiveType do not match (!)");
|
||||||
|
|
||||||
|
// do no tallow by default - problem is that self-overlapping parts of this geometry will
|
||||||
|
// not be in a all-same transparency but will already alpha-cover themselves with blending.
|
||||||
|
// This is not what the UnifiedTransparencePrimitive2D defines: It requires all it's
|
||||||
|
// content to be uniformely transparent.
|
||||||
|
// To check, acitvate and draw a wide transparent self-crossing line/curve
|
||||||
|
static bool bAllowed(false);
|
||||||
|
|
||||||
|
bDrawTransparentUsed = bAllowed && tryDrawPolygonStrokePrimitive2DDirect(*pPoStroke, rUniTransparenceCandidate.getTransparence());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// #i# need to wait for #i101378# which is in CWS vcl112 to directly paint transparent hairlines
|
|
||||||
//case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D:
|
|
||||||
//{
|
|
||||||
// // single transparent PolygonHairlinePrimitive2D identified, use directly
|
|
||||||
// const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive);
|
|
||||||
// OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)");
|
|
||||||
// break;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -431,6 +636,14 @@ namespace drawinglayer
|
|||||||
}
|
}
|
||||||
case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
|
case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
|
||||||
{
|
{
|
||||||
|
// try to use directly
|
||||||
|
const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive2D = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate);
|
||||||
|
|
||||||
|
if(tryDrawPolygonStrokePrimitive2DDirect(rPolygonStrokePrimitive2D, 0.0))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// the stroke primitive may be decomposed to filled polygons. To keep
|
// the stroke primitive may be decomposed to filled polygons. To keep
|
||||||
// evtl. set DrawModes aka DRAWMODE_BLACKLINE, DRAWMODE_GRAYLINE,
|
// evtl. set DrawModes aka DRAWMODE_BLACKLINE, DRAWMODE_GRAYLINE,
|
||||||
// DRAWMODE_GHOSTEDLINE, DRAWMODE_WHITELINE or DRAWMODE_SETTINGSLINE
|
// DRAWMODE_GHOSTEDLINE, DRAWMODE_WHITELINE or DRAWMODE_SETTINGSLINE
|
||||||
@@ -459,9 +672,7 @@ namespace drawinglayer
|
|||||||
// as filled polygons is geometrically corret but looks wrong since polygon filling avoids
|
// as filled polygons is geometrically corret but looks wrong since polygon filling avoids
|
||||||
// the right and bottom pixels. The used method evaluates that and takes the correct action,
|
// the right and bottom pixels. The used method evaluates that and takes the correct action,
|
||||||
// including calling recursively with decomposition if line is wide enough
|
// including calling recursively with decomposition if line is wide enough
|
||||||
const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate);
|
RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive2D);
|
||||||
|
|
||||||
RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore DrawMode
|
// restore DrawMode
|
||||||
|
@@ -25,6 +25,15 @@
|
|||||||
#include "vclprocessor2d.hxx"
|
#include "vclprocessor2d.hxx"
|
||||||
#include <vcl/outdev.hxx>
|
#include <vcl/outdev.hxx>
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// predefines
|
||||||
|
|
||||||
|
namespace drawinglayer { namespace primitive2d {
|
||||||
|
class PolyPolygonColorPrimitive2D;
|
||||||
|
class PolygonHairlinePrimitive2D;
|
||||||
|
class PolygonStrokePrimitive2D;
|
||||||
|
}}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace drawinglayer
|
namespace drawinglayer
|
||||||
@@ -46,6 +55,11 @@ namespace drawinglayer
|
|||||||
*/
|
*/
|
||||||
virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate);
|
virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate);
|
||||||
|
|
||||||
|
// some helpers to try direct paints (shortcuts)
|
||||||
|
bool tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D& rSource, double fTransparency);
|
||||||
|
bool tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D& rSource, double fTransparency);
|
||||||
|
bool tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D& rSource, double fTransparency);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// constructor/destructor
|
/// constructor/destructor
|
||||||
VclPixelProcessor2D(
|
VclPixelProcessor2D(
|
||||||
|
@@ -782,86 +782,6 @@ namespace drawinglayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// direct draw of PolyPolygon with color
|
|
||||||
void VclProcessor2D::RenderPolyPolygonColorPrimitive2D(const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate)
|
|
||||||
{
|
|
||||||
const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor()));
|
|
||||||
mpOutputDevice->SetFillColor(Color(aPolygonColor));
|
|
||||||
mpOutputDevice->SetLineColor();
|
|
||||||
|
|
||||||
basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
|
|
||||||
aLocalPolyPolygon.transform(maCurrentTransformation);
|
|
||||||
|
|
||||||
static bool bCheckTrapezoidDecomposition(false);
|
|
||||||
static bool bShowOutlinesThere(false);
|
|
||||||
if(bCheckTrapezoidDecomposition)
|
|
||||||
{
|
|
||||||
// clip against discrete ViewPort
|
|
||||||
const basegfx::B2DRange& rDiscreteViewport = getViewInformation2D().getDiscreteViewport();
|
|
||||||
aLocalPolyPolygon = basegfx::tools::clipPolyPolygonOnRange(
|
|
||||||
aLocalPolyPolygon, rDiscreteViewport, true, false);
|
|
||||||
|
|
||||||
if(aLocalPolyPolygon.count())
|
|
||||||
{
|
|
||||||
// subdivide
|
|
||||||
aLocalPolyPolygon = basegfx::tools::adaptiveSubdivideByDistance(
|
|
||||||
aLocalPolyPolygon, 0.5);
|
|
||||||
|
|
||||||
// trapezoidize
|
|
||||||
basegfx::B2DTrapezoidVector aB2DTrapezoidVector;
|
|
||||||
basegfx::tools::trapezoidSubdivide(aB2DTrapezoidVector, aLocalPolyPolygon);
|
|
||||||
|
|
||||||
const sal_uInt32 nCount(aB2DTrapezoidVector.size());
|
|
||||||
|
|
||||||
if(nCount)
|
|
||||||
{
|
|
||||||
basegfx::BColor aInvPolygonColor(aPolygonColor);
|
|
||||||
aInvPolygonColor.invert();
|
|
||||||
|
|
||||||
for(sal_uInt32 a(0); a < nCount; a++)
|
|
||||||
{
|
|
||||||
const basegfx::B2DPolygon aTempPolygon(aB2DTrapezoidVector[a].getB2DPolygon());
|
|
||||||
|
|
||||||
if(bShowOutlinesThere)
|
|
||||||
{
|
|
||||||
mpOutputDevice->SetFillColor(Color(aPolygonColor));
|
|
||||||
mpOutputDevice->SetLineColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
mpOutputDevice->DrawPolygon(aTempPolygon);
|
|
||||||
|
|
||||||
if(bShowOutlinesThere)
|
|
||||||
{
|
|
||||||
mpOutputDevice->SetFillColor();
|
|
||||||
mpOutputDevice->SetLineColor(Color(aInvPolygonColor));
|
|
||||||
mpOutputDevice->DrawPolyLine(aTempPolygon, 0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
|
|
||||||
|
|
||||||
if(mnPolygonStrokePrimitive2D
|
|
||||||
&& getOptionsDrawinglayer().IsAntiAliasing()
|
|
||||||
&& (mpOutputDevice->GetAntialiasing() & ANTIALIASING_ENABLE_B2DDRAW))
|
|
||||||
{
|
|
||||||
// when AA is on and this filled polygons are the result of stroked line geometry,
|
|
||||||
// draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons
|
|
||||||
mpOutputDevice->SetFillColor();
|
|
||||||
mpOutputDevice->SetLineColor(Color(aPolygonColor));
|
|
||||||
const sal_uInt32 nCount(aLocalPolyPolygon.count());
|
|
||||||
|
|
||||||
for(sal_uInt32 a(0); a < nCount; a++)
|
|
||||||
{
|
|
||||||
mpOutputDevice->DrawPolyLine(aLocalPolyPolygon.getB2DPolygon(a), 0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mask group. Force output to VDev and create mask from given mask
|
// mask group. Force output to VDev and create mask from given mask
|
||||||
void VclProcessor2D::RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate)
|
void VclProcessor2D::RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate)
|
||||||
{
|
{
|
||||||
|
@@ -38,7 +38,6 @@ namespace drawinglayer { namespace primitive2d {
|
|||||||
class FillGraphicPrimitive2D;
|
class FillGraphicPrimitive2D;
|
||||||
class PolyPolygonGradientPrimitive2D;
|
class PolyPolygonGradientPrimitive2D;
|
||||||
class PolyPolygonGraphicPrimitive2D;
|
class PolyPolygonGraphicPrimitive2D;
|
||||||
class PolyPolygonColorPrimitive2D;
|
|
||||||
class MetafilePrimitive2D;
|
class MetafilePrimitive2D;
|
||||||
class MaskPrimitive2D;
|
class MaskPrimitive2D;
|
||||||
class UnifiedTransparencePrimitive2D;
|
class UnifiedTransparencePrimitive2D;
|
||||||
@@ -95,7 +94,6 @@ namespace drawinglayer
|
|||||||
void RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
|
void RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
|
||||||
void RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate);
|
void RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate);
|
||||||
void RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate);
|
void RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate);
|
||||||
void RenderPolyPolygonColorPrimitive2D(const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate);
|
|
||||||
void RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate);
|
void RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate);
|
||||||
void RenderModifiedColorPrimitive2D(const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate);
|
void RenderModifiedColorPrimitive2D(const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate);
|
||||||
void RenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate);
|
void RenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate);
|
||||||
|
@@ -534,6 +534,7 @@ public:
|
|||||||
SAL_DLLPRIVATE bool ImpTryDrawPolyLineDirect(
|
SAL_DLLPRIVATE bool ImpTryDrawPolyLineDirect(
|
||||||
const basegfx::B2DPolygon& rB2DPolygon,
|
const basegfx::B2DPolygon& rB2DPolygon,
|
||||||
double fLineWidth = 0.0,
|
double fLineWidth = 0.0,
|
||||||
|
double fTransparency = 0.0,
|
||||||
basegfx::B2DLineJoin eLineJoin = basegfx::B2DLINEJOIN_NONE,
|
basegfx::B2DLineJoin eLineJoin = basegfx::B2DLINEJOIN_NONE,
|
||||||
com::sun::star::drawing::LineCap eLineCap = com::sun::star::drawing::LineCap_BUTT);
|
com::sun::star::drawing::LineCap eLineCap = com::sun::star::drawing::LineCap_BUTT);
|
||||||
|
|
||||||
@@ -673,6 +674,12 @@ public:
|
|||||||
double fLineWidth = 0.0,
|
double fLineWidth = 0.0,
|
||||||
basegfx::B2DLineJoin = basegfx::B2DLINEJOIN_ROUND,
|
basegfx::B2DLineJoin = basegfx::B2DLINEJOIN_ROUND,
|
||||||
com::sun::star::drawing::LineCap = com::sun::star::drawing::LineCap_BUTT);
|
com::sun::star::drawing::LineCap = com::sun::star::drawing::LineCap_BUTT);
|
||||||
|
bool TryDrawPolyLineDirect(
|
||||||
|
const basegfx::B2DPolygon& rB2DPolygon,
|
||||||
|
double fLineWidth = 0.0,
|
||||||
|
double fTransparency = 0.0,
|
||||||
|
basegfx::B2DLineJoin eLineJoin = basegfx::B2DLINEJOIN_NONE,
|
||||||
|
com::sun::star::drawing::LineCap eLineCap = com::sun::star::drawing::LineCap_BUTT);
|
||||||
|
|
||||||
/** Render the given polygon as a line stroke
|
/** Render the given polygon as a line stroke
|
||||||
|
|
||||||
|
@@ -2148,6 +2148,7 @@ void OutputDevice::ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPo
|
|||||||
bool OutputDevice::ImpTryDrawPolyLineDirect(
|
bool OutputDevice::ImpTryDrawPolyLineDirect(
|
||||||
const basegfx::B2DPolygon& rB2DPolygon,
|
const basegfx::B2DPolygon& rB2DPolygon,
|
||||||
double fLineWidth,
|
double fLineWidth,
|
||||||
|
double fTransparency,
|
||||||
basegfx::B2DLineJoin eLineJoin,
|
basegfx::B2DLineJoin eLineJoin,
|
||||||
com::sun::star::drawing::LineCap eLineCap)
|
com::sun::star::drawing::LineCap eLineCap)
|
||||||
{
|
{
|
||||||
@@ -2177,13 +2178,64 @@ bool OutputDevice::ImpTryDrawPolyLineDirect(
|
|||||||
// draw the polyline
|
// draw the polyline
|
||||||
return mpGraphics->DrawPolyLine(
|
return mpGraphics->DrawPolyLine(
|
||||||
aB2DPolygon,
|
aB2DPolygon,
|
||||||
0.0,
|
fTransparency,
|
||||||
aB2DLineWidth,
|
aB2DLineWidth,
|
||||||
eLineJoin,
|
eLineJoin,
|
||||||
eLineCap,
|
eLineCap,
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OutputDevice::TryDrawPolyLineDirect(
|
||||||
|
const basegfx::B2DPolygon& rB2DPolygon,
|
||||||
|
double fLineWidth,
|
||||||
|
double fTransparency,
|
||||||
|
basegfx::B2DLineJoin eLineJoin,
|
||||||
|
com::sun::star::drawing::LineCap eLineCap)
|
||||||
|
{
|
||||||
|
// AW: Do NOT paint empty PolyPolygons
|
||||||
|
if(!rB2DPolygon.count())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// we need a graphics
|
||||||
|
if( !mpGraphics )
|
||||||
|
if( !ImplGetGraphics() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( mbInitClipRegion )
|
||||||
|
ImplInitClipRegion();
|
||||||
|
|
||||||
|
if( mbOutputClipped )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if( mbInitLineColor )
|
||||||
|
ImplInitLineColor();
|
||||||
|
|
||||||
|
const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
|
||||||
|
&& mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
|
||||||
|
&& ROP_OVERPAINT == GetRasterOp()
|
||||||
|
&& IsLineColor());
|
||||||
|
|
||||||
|
if(bTryAA)
|
||||||
|
{
|
||||||
|
if(ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, fTransparency, eLineJoin, eLineCap))
|
||||||
|
{
|
||||||
|
// worked, add metafile action (if recorded) and return true
|
||||||
|
if( mpMetaFile )
|
||||||
|
{
|
||||||
|
LineInfo aLineInfo;
|
||||||
|
if( fLineWidth != 0.0 )
|
||||||
|
aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
|
||||||
|
const Polygon aToolsPolygon( rB2DPolygon );
|
||||||
|
mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void OutputDevice::DrawPolyLine(
|
void OutputDevice::DrawPolyLine(
|
||||||
const basegfx::B2DPolygon& rB2DPolygon,
|
const basegfx::B2DPolygon& rB2DPolygon,
|
||||||
double fLineWidth,
|
double fLineWidth,
|
||||||
@@ -2191,8 +2243,6 @@ void OutputDevice::DrawPolyLine(
|
|||||||
com::sun::star::drawing::LineCap eLineCap)
|
com::sun::star::drawing::LineCap eLineCap)
|
||||||
{
|
{
|
||||||
DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
|
DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
|
||||||
(void)eLineJoin; // ATM used in UNX, but not in WNT, access it for warning-free
|
|
||||||
(void)eLineCap;
|
|
||||||
|
|
||||||
if( mpMetaFile )
|
if( mpMetaFile )
|
||||||
{
|
{
|
||||||
@@ -2226,7 +2276,7 @@ void OutputDevice::DrawPolyLine(
|
|||||||
&& IsLineColor());
|
&& IsLineColor());
|
||||||
|
|
||||||
// use b2dpolygon drawing if possible
|
// use b2dpolygon drawing if possible
|
||||||
if(bTryAA && ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, eLineJoin, eLineCap))
|
if(bTryAA && ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, 0.0, eLineJoin, eLineCap))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user