From 99501a839f6d777c24bc9210787fd14dc3aad67d Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Thu, 21 Feb 2013 17:51:40 +0100 Subject: #120616# Corrected SVG gradient primitive and it's decomposition Conflicts: drawinglayer/source/primitive2d/svggradientprimitive2d.cxx Change-Id: I04c148303e7153a5376eae79803c540f6eba0b00 --- .../primitive2d/svggradientprimitive2d.hxx | 9 +++ .../source/primitive2d/svggradientprimitive2d.cxx | 83 ++++++++++++++++------ 2 files changed, 69 insertions(+), 23 deletions(-) (limited to 'drawinglayer') diff --git a/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx index 39115a76d938..2c9e34fe96e1 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx @@ -111,6 +111,11 @@ namespace drawinglayer bool mbSingleEntry : 1; bool mbFullyOpaque : 1; + // true = interpret in unit coordinate system -> object aspect ratio will scale result + // false = interpret in object coordinate system -> object aspect ratio will not scale result + // (related to SVG's gradientUnits (userSpaceOnUse|objectBoundingBox) + bool mbUseUnitCoordinates : 1; + protected: /// local helpers Primitive2DSequence createSingleGradientEntryFill() const; @@ -145,6 +150,7 @@ namespace drawinglayer const basegfx::B2DPolyPolygon& rPolyPolygon, const SvgGradientEntryVector& rGradientEntries, const basegfx::B2DPoint& rStart, + bool bUseUnitCoordinates, SpreadMethod aSpreadMethod = Spread_pad); virtual ~SvgGradientHelper() {} @@ -152,6 +158,7 @@ namespace drawinglayer const basegfx::B2DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; } const SvgGradientEntryVector& getGradientEntries() const { return maGradientEntries; } const basegfx::B2DPoint& getStart() const { return maStart; } + bool getUseUnitCoordinates() const { return mbUseUnitCoordinates; } SpreadMethod getSpreadMethod() const { return maSpreadMethod; } /// compare operator @@ -194,6 +201,7 @@ namespace drawinglayer const SvgGradientEntryVector& rGradientEntries, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd, + bool bUseUnitCoordinates, SpreadMethod aSpreadMethod = Spread_pad); virtual ~SvgLinearGradientPrimitive2D() {} @@ -261,6 +269,7 @@ namespace drawinglayer const SvgGradientEntryVector& rGradientEntries, const basegfx::B2DPoint& rStart, double fRadius, + bool bUseUnitCoordinates, SpreadMethod aSpreadMethod = Spread_pad, const basegfx::B2DPoint* pFocal = 0); diff --git a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx index a8c60da51299..98dc1ca966d3 100644 --- a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx @@ -283,6 +283,7 @@ namespace drawinglayer const basegfx::B2DPolyPolygon& rPolyPolygon, const SvgGradientEntryVector& rGradientEntries, const basegfx::B2DPoint& rStart, + bool bUseUnitCoordinates, SpreadMethod aSpreadMethod) : maPolyPolygon(rPolyPolygon), maGradientEntries(rGradientEntries), @@ -291,7 +292,8 @@ namespace drawinglayer mbPreconditionsChecked(false), mbCreatesContent(false), mbSingleEntry(false), - mbFullyOpaque(true) + mbFullyOpaque(true), + mbUseUnitCoordinates(bUseUnitCoordinates) { } @@ -302,6 +304,7 @@ namespace drawinglayer return (getPolyPolygon() == rCompare.getPolyPolygon() && getGradientEntries() == rCompare.getGradientEntries() && getStart() == rCompare.getStart() + && getUseUnitCoordinates() == rCompare.getUseUnitCoordinates() && getSpreadMethod() == rCompare.getSpreadMethod()); } @@ -388,20 +391,37 @@ namespace drawinglayer basegfx::tools::createScaleTranslateB2DHomMatrix( fPolyWidth, fPolyHeight, aPolyRange.getMinX(), aPolyRange.getMinY())); + basegfx::B2DHomMatrix aUnitGradientToObject; + static bool bInterpretAbsolute(true); - // create unit transform from unit vector [0.0 .. 1.0] along the X-Axis to given - // gradient vector defined by Start,End - const basegfx::B2DVector aVector(getEnd() - getStart()); - const double fVectorLength(aVector.getLength()); - basegfx::B2DHomMatrix aUnitGradientToGradient; - - aUnitGradientToGradient.scale(fVectorLength, 1.0); - aUnitGradientToGradient.rotate(atan2(aVector.getY(), aVector.getX())); - aUnitGradientToGradient.translate(getStart().getX(), getStart().getY()); - - // create full transform from unit gradient coordinates to object coordinates - // including the SvgGradient transformation - basegfx::B2DHomMatrix aUnitGradientToObject(aObjectTransform * aUnitGradientToGradient); + if(getUseUnitCoordinates()) + { + // interpret in unit coordinate system -> object aspect ratio will scale result + // create unit transform from unit vector [0.0 .. 1.0] along the X-Axis to given + // gradient vector defined by Start,End + const basegfx::B2DVector aVector(getEnd() - getStart()); + const double fVectorLength(aVector.getLength()); + basegfx::B2DHomMatrix aUnitGradientToGradient; + + aUnitGradientToGradient.scale(fVectorLength, 1.0); + aUnitGradientToGradient.rotate(atan2(aVector.getY(), aVector.getX())); + aUnitGradientToGradient.translate(getStart().getX(), getStart().getY()); + + // create full transform from unit gradient coordinates to object coordinates + // including the SvgGradient transformation + aUnitGradientToObject = aObjectTransform * aUnitGradientToGradient; + } + else + { + // interpret in object coordinate system -> object aspect ratio will not scale result + const basegfx::B2DPoint aStart(aObjectTransform * getStart()); + const basegfx::B2DPoint aEnd(aObjectTransform * getEnd()); + const basegfx::B2DVector aVector(aEnd - aStart); + + aUnitGradientToObject.scale(aVector.getLength(), 1.0); + aUnitGradientToObject.rotate(atan2(aVector.getY(), aVector.getX())); + aUnitGradientToObject.translate(aStart.getX(), aStart.getY()); + } // create inverse from it basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject); @@ -525,9 +545,10 @@ namespace drawinglayer const SvgGradientEntryVector& rGradientEntries, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd, + bool bUseUnitCoordinates, SpreadMethod aSpreadMethod) : BufferedDecompositionPrimitive2D(), - SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod), + SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, bUseUnitCoordinates, aSpreadMethod), maEnd(rEnd) { } @@ -698,16 +719,31 @@ namespace drawinglayer basegfx::tools::createScaleTranslateB2DHomMatrix( fPolyWidth, fPolyHeight, aPolyRange.getMinX(), aPolyRange.getMinY())); + basegfx::B2DHomMatrix aUnitGradientToObject; + static bool bInterpretAbsolute(true); - // create unit transform from unit vector to given linear gradient vector - basegfx::B2DHomMatrix aUnitGradientToGradient; + if(getUseUnitCoordinates()) + { + // interpret in unit coordinate system -> object aspect ratio will scale result + // create unit transform from unit vector to given linear gradient vector + basegfx::B2DHomMatrix aUnitGradientToGradient; - aUnitGradientToGradient.scale(getRadius(), getRadius()); - aUnitGradientToGradient.translate(getStart().getX(), getStart().getY()); + aUnitGradientToGradient.scale(getRadius(), getRadius()); + aUnitGradientToGradient.translate(getStart().getX(), getStart().getY()); - // create full transform from unit gradient coordinates to object coordinates - // including the SvgGradient transformation - basegfx::B2DHomMatrix aUnitGradientToObject(aObjectTransform * aUnitGradientToGradient); + // create full transform from unit gradient coordinates to object coordinates + // including the SvgGradient transformation + aUnitGradientToObject = aObjectTransform * aUnitGradientToGradient; + } + else + { + // interpret in object coordinate system -> object aspect ratio will not scale result + const double fRadius((aObjectTransform * basegfx::B2DVector(getRadius(), 0.0)).getLength()); + const basegfx::B2DPoint aStart(aObjectTransform * getStart()); + + aUnitGradientToObject.scale(fRadius, fRadius); + aUnitGradientToObject.translate(aStart.getX(), aStart.getY()); + } // create inverse from it basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject); @@ -780,10 +816,11 @@ namespace drawinglayer const SvgGradientEntryVector& rGradientEntries, const basegfx::B2DPoint& rStart, double fRadius, + bool bUseUnitCoordinates, SpreadMethod aSpreadMethod, const basegfx::B2DPoint* pFocal) : BufferedDecompositionPrimitive2D(), - SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod), + SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, bUseUnitCoordinates, aSpreadMethod), mfRadius(fRadius), maFocal(rStart), maFocalVector(0.0, 0.0), -- cgit