summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2016-07-01 15:50:00 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2016-07-07 17:33:19 +0200
commite15322442b9cc30122349d365a41c7a7bfd83322 (patch)
tree8763fb0f794842fb4d0f8ff1ac63a5e336f7b473
parent8dbd74741609d9ce5eac3501d2c304d98bde1d76 (diff)
tdf#82214 optimize PatternFillPrimitive and SVG
Use buffering in the drawinglayer, and don't do slow stuff in the windows gdi renderer. Conflicts: svgio/source/svgreader/svgstyleattributes.cxx Change-Id: Id955ee6a3b03e568c2678f02d77af35d2e5ba1d4
-rw-r--r--drawinglayer/source/primitive2d/patternfillprimitive2d.cxx73
-rw-r--r--svgio/source/svgreader/svgstyleattributes.cxx89
2 files changed, 99 insertions, 63 deletions
diff --git a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
index b84a577e2310..225cb2fd8084 100644
--- a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
@@ -32,8 +32,8 @@
using namespace com::sun::star;
-#define MAXIMUM_SQUARE_LENGTH (164.0)
-#define MINIMUM_SQUARE_LENGTH (32.0)
+#define MAXIMUM_SQUARE_LENGTH (186.0)
+#define MINIMUM_SQUARE_LENGTH (16.0)
#define MINIMUM_TILES_LENGTH (3)
@@ -259,57 +259,58 @@ namespace drawinglayer
Primitive2DSequence PatternFillPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
{
- if(0 == mnDiscreteWidth || 0 == mnDiscreteHeight)
+ // The existing bufferd decomposition uses a buffer in the remembered
+ // size or none if sizes are zero. Get new needed sizes which depend on
+ // the given ViewInformation
+ bool bResetBuffering = false;
+ sal_uInt32 nW(0);
+ sal_uInt32 nH(0);
+ calculateNeededDiscreteBufferSize(nW, nH, rViewInformation);
+ const bool bBufferingCurrentlyUsed(0 != mnDiscreteWidth && 0 != mnDiscreteHeight);
+ const bool bBufferingNextUsed(0 != nW && 0 != nH);
+
+ if(bBufferingNextUsed)
{
- // Currently no buffering is used. Check if the resulting discrete sizes
- // in the current situation would be good for buffering from now on
- PatternFillPrimitive2D* pThat = const_cast< PatternFillPrimitive2D* >(this);
-
- calculateNeededDiscreteBufferSize(pThat->mnDiscreteWidth, pThat->mnDiscreteHeight, rViewInformation);
- }
- else
- {
- // The existing bufferd decomposition uses a buffer in the remembered
- // size. Get new needed sizes which depend on the given ViewInformation
- sal_uInt32 nW(0);
- sal_uInt32 nH(0);
- calculateNeededDiscreteBufferSize(nW, nH, rViewInformation);
-
- if(0 != nW && 0 != nH)
+ // buffering is now possible
+ if(bBufferingCurrentlyUsed)
{
- // buffering is possible - check if reset is needed
- bool bResetBuffering = false;
-
if(nW > mnDiscreteWidth || nH > mnDiscreteHeight)
{
// Higher resolution is needed than used in the existing buffered
- // decomposition
+ // decomposition - create new one
bResetBuffering = true;
}
else if(double(nW * nH) / double(mnDiscreteWidth * mnDiscreteHeight) <= 0.5)
{
// Size has shrunk for 50% or more - it's worth to refresh the buffering
+ // to spare some ressources
bResetBuffering = true;
}
-
- if(bResetBuffering)
- {
- PatternFillPrimitive2D* pThat = const_cast< PatternFillPrimitive2D* >(this);
- pThat->mnDiscreteWidth = nW;
- pThat->mnDiscreteHeight = nH;
- pThat->setBuffered2DDecomposition(Primitive2DSequence());
- }
}
else
{
- // no buffering wanted or possible - clear decomposition to create a
- // new, unbuffered one
- PatternFillPrimitive2D* pThat = const_cast< PatternFillPrimitive2D* >(this);
- pThat->mnDiscreteWidth = 0;
- pThat->mnDiscreteHeight = 0;
- pThat->setBuffered2DDecomposition(Primitive2DSequence());
+ // currently no buffering used - reset evtl. unbuffered
+ // decomposition to start buffering
+ bResetBuffering = true;
}
}
+ else
+ {
+ // buffering is no longer possible
+ if(bBufferingCurrentlyUsed)
+ {
+ // reset decomposition to allow creation of unbuffered one
+ bResetBuffering = true;
+ }
+ }
+
+ if(bResetBuffering)
+ {
+ PatternFillPrimitive2D* pThat = const_cast< PatternFillPrimitive2D* >(this);
+ pThat->mnDiscreteWidth = nW;
+ pThat->mnDiscreteHeight = nH;
+ pThat->setBuffered2DDecomposition(Primitive2DContainer());
+ }
// call parent
return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
index 4735887e4171..fc373da232ab 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -669,40 +669,75 @@ namespace svgio
if(basegfx::fTools::more(fStrokeWidth, 0.0))
{
- // get LineJoin, LineCap and stroke array
- const basegfx::B2DLineJoin aB2DLineJoin(StrokeLinejoinToB2DLineJoin(getStrokeLinejoin()));
- const com::sun::star::drawing::LineCap aLineCap(StrokeLinecapToDrawingLineCap(getStrokeLinecap()));
- ::std::vector< double > aDashArray;
+ drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive;
- if(!getStrokeDasharray().empty())
+ // if we have a line with two identical points it is not really a line,
+ // but used by SVG sometimes to paint a single dot.In that case, create
+ // the geometry for a single dot
+ if(1 == rPath.count())
{
- aDashArray = solveSvgNumberVector(getStrokeDasharray(), mrOwner, length);
+ const basegfx::B2DPolygon aSingle(rPath.getB2DPolygon(0));
+
+ if(2 == aSingle.count() && aSingle.getB2DPoint(0).equal(aSingle.getB2DPoint(1)))
+ {
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(
+ basegfx::tools::createPolygonFromCircle(
+ aSingle.getB2DPoint(0),
+ fStrokeWidth * (1.44 * 0.5))),
+ pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0));
+ }
}
- // todo: Handle getStrokeDashOffset()
+ if(!aNewLinePrimitive.is())
+ {
+ // get LineJoin, LineCap and stroke array
+ const basegfx::B2DLineJoin aB2DLineJoin(StrokeLinejoinToB2DLineJoin(getStrokeLinejoin()));
+ const css::drawing::LineCap aLineCap(StrokeLinecapToDrawingLineCap(getStrokeLinecap()));
+ ::std::vector< double > aDashArray;
- // prepare line attribute
- drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive;
- const drawinglayer::attribute::LineAttribute aLineAttribute(
- pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0),
- fStrokeWidth,
- aB2DLineJoin,
- aLineCap);
+ if(!getStrokeDasharray().empty())
+ {
+ aDashArray = solveSvgNumberVector(getStrokeDasharray(), mrOwner);
+ }
- if(aDashArray.empty())
- {
- aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
- rPath,
- aLineAttribute);
- }
- else
- {
- const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashArray);
+ // convert svg:stroke-miterlimit to LineAttrute:mfMiterMinimumAngle
+ // The default needs to be set explicitely, because svg default <> Draw default
+ double fMiterMinimumAngle;
+ if (getStrokeMiterLimit().isSet())
+ {
+ fMiterMinimumAngle = 2.0 * asin(1.0/getStrokeMiterLimit().getNumber());
+ }
+ else
+ {
+ fMiterMinimumAngle = 2.0 * asin(0.25); // 1.0/default 4.0
+ }
- aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
- rPath,
- aLineAttribute,
- aStrokeAttribute);
+ // todo: Handle getStrokeDashOffset()
+
+ // prepare line attribute
+ const drawinglayer::attribute::LineAttribute aLineAttribute(
+ pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0),
+ fStrokeWidth,
+ aB2DLineJoin,
+ aLineCap,
+ fMiterMinimumAngle);
+
+ if(aDashArray.empty())
+ {
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+ rPath,
+ aLineAttribute);
+ }
+ else
+ {
+ const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashArray);
+
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+ rPath,
+ aLineAttribute,
+ aStrokeAttribute);
+ }
}
if(pStrokeGradient || pStrokePattern)