summaryrefslogtreecommitdiff
path: root/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'drawinglayer/source/processor2d/vclpixelprocessor2d.cxx')
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx257
1 files changed, 234 insertions, 23 deletions
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index a320d1a88c78..a486dd84b578 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -92,6 +92,141 @@ namespace drawinglayer
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)
{
switch(rCandidate.getPrimitive2DID())
@@ -169,8 +304,17 @@ namespace drawinglayer
}
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
- RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), true);
+ RenderPolygonHairlinePrimitive2D(rPolygonHairlinePrimitive2D, true);
break;
}
case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
@@ -240,8 +384,53 @@ namespace drawinglayer
}
case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
{
- // direct draw of PolyPolygon with color
- RenderPolyPolygonColorPrimitive2D(static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate));
+ // try to use directly
+ 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;
}
case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
@@ -313,25 +502,41 @@ namespace drawinglayer
// single transparent PolyPolygon identified, use directly
const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive);
OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)");
- const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor()));
- mpOutputDevice->SetFillColor(Color(aPolygonColor));
- mpOutputDevice->SetLineColor();
-
- basegfx::B2DPolyPolygon aLocalPolyPolygon(pPoPoColor->getB2DPolyPolygon());
- aLocalPolyPolygon.transform(maCurrentTransformation);
-
- mpOutputDevice->DrawTransparent(aLocalPolyPolygon, rUniTransparenceCandidate.getTransparence());
- bDrawTransparentUsed = true;
+ bDrawTransparentUsed = tryDrawPolyPolygonColorPrimitive2DDirect(*pPoPoColor, rUniTransparenceCandidate.getTransparence());
+ break;
+ }
+ 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 (!)");
+
+ // 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;
}
- // #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:
{
+ // 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
// evtl. set DrawModes aka DRAWMODE_BLACKLINE, DRAWMODE_GRAYLINE,
// 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
// 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
- const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate);
-
- RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive);
+ RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive2D);
}
// restore DrawMode