summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drawinglayer/source/primitive2d/svggradientprimitive2d.cxx203
-rw-r--r--drawinglayer/source/processor2d/cairopixelprocessor2d.cxx223
-rw-r--r--include/drawinglayer/primitive2d/svggradientprimitive2d.hxx22
-rw-r--r--include/drawinglayer/processor2d/cairopixelprocessor2d.hxx10
4 files changed, 351 insertions, 107 deletions
diff --git a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
index 69881695a22b..4b8a5cb4ab86 100644
--- a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
@@ -104,7 +104,6 @@ namespace drawinglayer::primitive2d
void SvgGradientHelper::checkPreconditions()
{
- mbPreconditionsChecked = true;
const SvgGradientEntryVector& rEntries = getGradientEntries();
if(rEntries.empty())
@@ -356,7 +355,6 @@ namespace drawinglayer::primitive2d
maGradientEntries(std::move(rGradientEntries)),
maStart(rStart),
maSpreadMethod(aSpreadMethod),
- mbPreconditionsChecked(false),
mbCreatesContent(false),
mbSingleEntry(false),
mbFullyOpaque(true),
@@ -468,13 +466,56 @@ namespace drawinglayer::primitive2d
}
}
- Primitive2DReference SvgLinearGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ basegfx::B2DHomMatrix SvgLinearGradientPrimitive2D::createUnitGradientToObjectTransformation() const
{
- if(!getPreconditionsChecked())
+ const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
+ const double fPolyWidth(aPolyRange.getWidth());
+ const double fPolyHeight(aPolyRange.getHeight());
+
+ // create ObjectTransform based on polygon range
+ const basegfx::B2DHomMatrix aObjectTransform(
+ basegfx::utils::createScaleTranslateB2DHomMatrix(
+ fPolyWidth, fPolyHeight,
+ aPolyRange.getMinX(), aPolyRange.getMinY()));
+ basegfx::B2DHomMatrix aUnitGradientToObject;
+
+ if(getUseUnitCoordinates())
{
- const_cast< SvgLinearGradientPrimitive2D* >(this)->checkPreconditions();
+ // 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());
+
+ aUnitGradientToObject.scale(fVectorLength, 1.0);
+ aUnitGradientToObject.rotate(atan2(aVector.getY(), aVector.getX()));
+ aUnitGradientToObject.translate(getStart().getX(), getStart().getY());
+
+ aUnitGradientToObject *= getGradientTransform();
+
+ // create full transform from unit gradient coordinates to object coordinates
+ // including the SvgGradient transformation
+ aUnitGradientToObject *= aObjectTransform;
+ }
+ 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());
+
+ aUnitGradientToObject *= getGradientTransform();
}
+ return aUnitGradientToObject;
+ }
+
+ Primitive2DReference SvgLinearGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
if(getSingleEntry())
{
// fill with last existing color
@@ -484,48 +525,7 @@ namespace drawinglayer::primitive2d
{
// at least two color stops in range [0.0 .. 1.0], sorted, non-null vector, not completely
// invisible, width and height to fill are not empty
- const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
- const double fPolyWidth(aPolyRange.getWidth());
- const double fPolyHeight(aPolyRange.getHeight());
-
- // create ObjectTransform based on polygon range
- const basegfx::B2DHomMatrix aObjectTransform(
- basegfx::utils::createScaleTranslateB2DHomMatrix(
- fPolyWidth, fPolyHeight,
- aPolyRange.getMinX(), aPolyRange.getMinY()));
- basegfx::B2DHomMatrix aUnitGradientToObject;
-
- 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());
-
- aUnitGradientToObject.scale(fVectorLength, 1.0);
- aUnitGradientToObject.rotate(atan2(aVector.getY(), aVector.getX()));
- aUnitGradientToObject.translate(getStart().getX(), getStart().getY());
-
- aUnitGradientToObject *= getGradientTransform();
-
- // create full transform from unit gradient coordinates to object coordinates
- // including the SvgGradient transformation
- aUnitGradientToObject *= aObjectTransform;
- }
- 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());
-
- aUnitGradientToObject *= getGradientTransform();
- }
+ basegfx::B2DHomMatrix aUnitGradientToObject(createUnitGradientToObjectTransformation());
// create inverse from it
basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject);
@@ -574,6 +574,8 @@ namespace drawinglayer::primitive2d
: SvgGradientHelper(rGradientTransform, rPolyPolygon, std::move(rGradientEntries), rStart, bUseUnitCoordinates, aSpreadMethod),
maEnd(rEnd)
{
+ // ensure Preconditions are checked
+ checkPreconditions();
}
SvgLinearGradientPrimitive2D::~SvgLinearGradientPrimitive2D()
@@ -647,8 +649,9 @@ namespace drawinglayer::primitive2d
if(isFocalSet())
{
- const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
- const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+ const basegfx::B2DVector aFocalVector(getFocal() - getStart());
+ const basegfx::B2DVector aTranslateFrom(aFocalVector * (maFocalLength - fScaleFrom));
+ const basegfx::B2DVector aTranslateTo(aFocalVector * (maFocalLength - fScaleTo));
rTargetColor.push_back(
new SvgRadialAtomPrimitive2D(
@@ -672,8 +675,9 @@ namespace drawinglayer::primitive2d
if(isFocalSet())
{
- const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
- const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+ const basegfx::B2DVector aFocalVector(getFocal() - getStart());
+ const basegfx::B2DVector aTranslateFrom(aFocalVector * (maFocalLength - fScaleFrom));
+ const basegfx::B2DVector aTranslateTo(aFocalVector * (maFocalLength - fScaleTo));
rTargetOpacity.push_back(
new SvgRadialAtomPrimitive2D(
@@ -691,13 +695,54 @@ namespace drawinglayer::primitive2d
}
}
- Primitive2DReference SvgRadialGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ basegfx::B2DHomMatrix SvgRadialGradientPrimitive2D::createUnitGradientToObjectTransformation() const
{
- if(!getPreconditionsChecked())
+ const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
+ const double fPolyWidth(aPolyRange.getWidth());
+ const double fPolyHeight(aPolyRange.getHeight());
+
+ // create ObjectTransform based on polygon range
+ const basegfx::B2DHomMatrix aObjectTransform(
+ basegfx::utils::createScaleTranslateB2DHomMatrix(
+ fPolyWidth, fPolyHeight,
+ aPolyRange.getMinX(), aPolyRange.getMinY()));
+ basegfx::B2DHomMatrix aUnitGradientToObject;
+
+ if(getUseUnitCoordinates())
{
- const_cast< SvgRadialGradientPrimitive2D* >(this)->checkPreconditions();
+ // interpret in unit coordinate system -> object aspect ratio will scale result
+ // create unit transform from unit vector to given linear gradient vector
+ aUnitGradientToObject.scale(getRadius(), getRadius());
+ aUnitGradientToObject.translate(getStart().getX(), getStart().getY());
+
+ if(!getGradientTransform().isIdentity())
+ {
+ aUnitGradientToObject = getGradientTransform() * aUnitGradientToObject;
+ }
+
+ // create full transform from unit gradient coordinates to object coordinates
+ // including the SvgGradient transformation
+ aUnitGradientToObject = aObjectTransform * aUnitGradientToObject;
}
+ else
+ {
+ // interpret in object coordinate system -> object aspect ratio will not scale result
+ // use X-Axis with radius, it was already made relative to object width when coming from
+ // SVG import
+ 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());
+
+ aUnitGradientToObject *= getGradientTransform();
+ }
+
+ return aUnitGradientToObject;
+ }
+ Primitive2DReference SvgRadialGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
if(getSingleEntry())
{
// fill with last existing color
@@ -707,46 +752,7 @@ namespace drawinglayer::primitive2d
{
// at least two color stops in range [0.0 .. 1.0], sorted, non-null vector, not completely
// invisible, width and height to fill are not empty
- const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
- const double fPolyWidth(aPolyRange.getWidth());
- const double fPolyHeight(aPolyRange.getHeight());
-
- // create ObjectTransform based on polygon range
- const basegfx::B2DHomMatrix aObjectTransform(
- basegfx::utils::createScaleTranslateB2DHomMatrix(
- fPolyWidth, fPolyHeight,
- aPolyRange.getMinX(), aPolyRange.getMinY()));
- basegfx::B2DHomMatrix aUnitGradientToObject;
-
- if(getUseUnitCoordinates())
- {
- // interpret in unit coordinate system -> object aspect ratio will scale result
- // create unit transform from unit vector to given linear gradient vector
- aUnitGradientToObject.scale(getRadius(), getRadius());
- aUnitGradientToObject.translate(getStart().getX(), getStart().getY());
-
- if(!getGradientTransform().isIdentity())
- {
- aUnitGradientToObject = getGradientTransform() * aUnitGradientToObject;
- }
-
- // create full transform from unit gradient coordinates to object coordinates
- // including the SvgGradient transformation
- aUnitGradientToObject = aObjectTransform * aUnitGradientToObject;
- }
- else
- {
- // interpret in object coordinate system -> object aspect ratio will not scale result
- // use X-Axis with radius, it was already made relative to object width when coming from
- // SVG import
- 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());
-
- aUnitGradientToObject *= getGradientTransform();
- }
+ basegfx::B2DHomMatrix aUnitGradientToObject(createUnitGradientToObjectTransformation());
// create inverse from it
basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject);
@@ -802,16 +808,15 @@ namespace drawinglayer::primitive2d
: SvgGradientHelper(rGradientTransform, rPolyPolygon, std::move(rGradientEntries), rStart, bUseUnitCoordinates, aSpreadMethod),
mfRadius(fRadius),
maFocal(rStart),
- maFocalVector(0.0, 0.0),
- maFocalLength(0.0),
- mbFocalSet(false)
+ maFocalLength(0.0)
{
if(pFocal && !pFocal->equal(getStart()))
{
maFocal = *pFocal;
- maFocalVector = maFocal - getStart();
- mbFocalSet = true;
}
+
+ // ensure Preconditions are checked
+ checkPreconditions();
}
SvgRadialGradientPrimitive2D::~SvgRadialGradientPrimitive2D()
diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index c3a1c74e764a..4fbddc3cf9ca 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -43,6 +43,7 @@
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
#include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
+#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
#include <drawinglayer/converters.hxx>
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
@@ -3213,6 +3214,216 @@ void CairoPixelProcessor2D::renderTextSimpleOrDecoratedPortionPrimitive2D(
}
}
+bool CairoPixelProcessor2D::handleSvgGradientHelper(
+ const primitive2d::SvgGradientHelper& rCandidate)
+{
+ // check PolyPolygon to be filled
+ const basegfx::B2DPolyPolygon& rPolyPolygon(rCandidate.getPolyPolygon());
+
+ if (!rPolyPolygon.count())
+ {
+ // no PolyPolygon, done
+ return true;
+ }
+
+ // calculate visible range
+ basegfx::B2DRange aPolyPolygonRange(rPolyPolygon.getB2DRange());
+ aPolyPolygonRange.transform(getViewInformation2D().getObjectToViewTransformation());
+ if (!getDiscreteViewRange(mpRT).overlaps(aPolyPolygonRange))
+ {
+ // not visible, done
+ return true;
+ }
+
+ if (!rCandidate.getCreatesContent())
+ {
+ // creates no content, done
+ return true;
+ }
+
+ if (rCandidate.getSingleEntry())
+ {
+ // only one color entry, fill with last existing color, done
+ primitive2d::SvgGradientEntryVector::const_reference aEntry(
+ rCandidate.getGradientEntries().back());
+ paintPolyPoylgonRGBA(rCandidate.getPolyPolygon(), aEntry.getColor(),
+ 1.0 - aEntry.getOpacity());
+
+ return true;
+ }
+
+ return false;
+}
+
+void CairoPixelProcessor2D::processSvgLinearGradientPrimitive2D(
+ const primitive2d::SvgLinearGradientPrimitive2D& rCandidate)
+{
+ // check for simple cases, returns if all necesary is already done
+ if (handleSvgGradientHelper(rCandidate))
+ {
+ // simple case, handled, done
+ return;
+ }
+
+ cairo_save(mpRT);
+
+ // set ObjectToView as regular transformation at CairoContext
+ const basegfx::B2DHomMatrix aTrans(getViewInformation2D().getObjectToViewTransformation());
+ cairo_matrix_t aMatrix;
+ cairo_matrix_init(&aMatrix, aTrans.a(), aTrans.b(), aTrans.c(), aTrans.d(), aTrans.e(),
+ aTrans.f());
+ cairo_set_matrix(mpRT, &aMatrix);
+
+ // create pattern using unit coordinates. Unit coordinates here means that
+ // the transformation provided by the primitive maps the linear gradient
+ // to (0,0) -> (1,0) at the unified object coordinates, along the unified
+ // X-Axis
+ cairo_pattern_t* pPattern(cairo_pattern_create_linear(0, 0, 1, 0));
+
+ // get pre-defined UnitGradientToObject transformation from primitive
+ // and invert to get ObjectToUnitGradient transform
+ basegfx::B2DHomMatrix aObjectToUnitGradient(
+ rCandidate.createUnitGradientToObjectTransformation());
+ aObjectToUnitGradient.invert();
+
+ // set ObjectToUnitGradient as transformation at gradient - patterns
+ // need the inverted transformation, see cairo documentation
+ cairo_matrix_init(&aMatrix, aObjectToUnitGradient.a(), aObjectToUnitGradient.b(),
+ aObjectToUnitGradient.c(), aObjectToUnitGradient.d(),
+ aObjectToUnitGradient.e(), aObjectToUnitGradient.f());
+ cairo_pattern_set_matrix(pPattern, &aMatrix);
+
+ // add color stops
+ const primitive2d::SvgGradientEntryVector& rGradientEntries(rCandidate.getGradientEntries());
+
+ for (const auto& entry : rGradientEntries)
+ {
+ const basegfx::BColor& rColor(entry.getColor());
+ cairo_pattern_add_color_stop_rgba(pPattern, entry.getOffset(), rColor.getRed(),
+ rColor.getGreen(), rColor.getBlue(), entry.getOpacity());
+ }
+
+ // set SpreadMethod. Note that we have no SpreadMethod::None because the
+ // source is SVG and SVG does also not have that (checked that)
+ switch (rCandidate.getSpreadMethod())
+ {
+ case primitive2d::SpreadMethod::Pad:
+ cairo_pattern_set_extend(pPattern, CAIRO_EXTEND_PAD);
+ break;
+ case primitive2d::SpreadMethod::Reflect:
+ cairo_pattern_set_extend(pPattern, CAIRO_EXTEND_REFLECT);
+ break;
+ case primitive2d::SpreadMethod::Repeat:
+ cairo_pattern_set_extend(pPattern, CAIRO_EXTEND_REPEAT);
+ break;
+ }
+
+ // get PathGeometry & paint it filed with gradient
+ cairo_new_path(mpRT);
+ getOrCreateFillGeometry(mpRT, rCandidate.getPolyPolygon());
+ cairo_set_source(mpRT, pPattern);
+ cairo_fill(mpRT);
+
+ // cleanup
+ cairo_pattern_destroy(pPattern);
+ cairo_restore(mpRT);
+}
+
+void CairoPixelProcessor2D::processSvgRadialGradientPrimitive2D(
+ const primitive2d::SvgRadialGradientPrimitive2D& rCandidate)
+{
+ // check for simple cases, returns if all necesary is already done
+ if (handleSvgGradientHelper(rCandidate))
+ {
+ // simple case, handled, done
+ return;
+ }
+
+ cairo_save(mpRT);
+
+ // set ObjectToView as regular transformation at CairoContext
+ const basegfx::B2DHomMatrix aTrans(getViewInformation2D().getObjectToViewTransformation());
+ cairo_matrix_t aMatrix;
+ cairo_matrix_init(&aMatrix, aTrans.a(), aTrans.b(), aTrans.c(), aTrans.d(), aTrans.e(),
+ aTrans.f());
+ cairo_set_matrix(mpRT, &aMatrix);
+
+ // get pre-defined UnitGradientToObject transformation from primitive
+ // and invert to get ObjectToUnitGradient transform
+ basegfx::B2DHomMatrix aObjectToUnitGradient(
+ rCandidate.createUnitGradientToObjectTransformation());
+ aObjectToUnitGradient.invert();
+
+ // prepare empty FocalVector
+ basegfx::B2DVector aFocalVector(0.0, 0.0);
+
+ if (rCandidate.isFocalSet())
+ {
+ // FocalPoint is used, create ObjectTransform based on polygon range
+ const basegfx::B2DRange aPolyRange(rCandidate.getPolyPolygon().getB2DRange());
+ const double fPolyWidth(aPolyRange.getWidth());
+ const double fPolyHeight(aPolyRange.getHeight());
+ const basegfx::B2DHomMatrix aObjectTransform(
+ basegfx::utils::createScaleTranslateB2DHomMatrix(
+ fPolyWidth, fPolyHeight, aPolyRange.getMinX(), aPolyRange.getMinY()));
+
+ // get vector, then transform to object coordinates, then to
+ // UnitGradient coordinates to be in the needed coordinate system
+ aFocalVector = basegfx::B2DVector(rCandidate.getStart() - rCandidate.getFocal());
+ aFocalVector *= aObjectTransform;
+ aFocalVector *= aObjectToUnitGradient;
+ }
+
+ // create pattern using unit coordinates. Unit coordinates here means that
+ // the transformation provided by the primitive maps the radial gradient
+ // to (0,0) as center, 1.0 as radius - which is the unit circle. The
+ // FocalPoint (if used) has to be relative to that, so - since unified
+ // center is at (0, 0), handling as vector is sufficient
+ cairo_pattern_t* pPattern(
+ cairo_pattern_create_radial(0, 0, 0, aFocalVector.getX(), aFocalVector.getY(), 1));
+
+ // set ObjectToUnitGradient as transformation at gradient - patterns
+ // need the inverted transformation, see cairo documentation
+ cairo_matrix_init(&aMatrix, aObjectToUnitGradient.a(), aObjectToUnitGradient.b(),
+ aObjectToUnitGradient.c(), aObjectToUnitGradient.d(),
+ aObjectToUnitGradient.e(), aObjectToUnitGradient.f());
+ cairo_pattern_set_matrix(pPattern, &aMatrix);
+
+ // add color stops
+ const primitive2d::SvgGradientEntryVector& rGradientEntries(rCandidate.getGradientEntries());
+
+ for (const auto& entry : rGradientEntries)
+ {
+ const basegfx::BColor& rColor(entry.getColor());
+ cairo_pattern_add_color_stop_rgba(pPattern, entry.getOffset(), rColor.getRed(),
+ rColor.getGreen(), rColor.getBlue(), entry.getOpacity());
+ }
+
+ // set SpreadMethod
+ switch (rCandidate.getSpreadMethod())
+ {
+ case primitive2d::SpreadMethod::Pad:
+ cairo_pattern_set_extend(pPattern, CAIRO_EXTEND_PAD);
+ break;
+ case primitive2d::SpreadMethod::Reflect:
+ cairo_pattern_set_extend(pPattern, CAIRO_EXTEND_REFLECT);
+ break;
+ case primitive2d::SpreadMethod::Repeat:
+ cairo_pattern_set_extend(pPattern, CAIRO_EXTEND_REPEAT);
+ break;
+ }
+
+ // get PathGeometry & paint it filed with gradient
+ cairo_new_path(mpRT);
+ getOrCreateFillGeometry(mpRT, rCandidate.getPolyPolygon());
+ cairo_set_source(mpRT, pPattern);
+ cairo_fill(mpRT);
+
+ // cleanup
+ cairo_pattern_destroy(pPattern);
+ cairo_restore(mpRT);
+}
+
void CairoPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
{
switch (rCandidate.getPrimitive2DID())
@@ -3359,6 +3570,18 @@ void CairoPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimit
static_cast<const primitive2d::TextDecoratedPortionPrimitive2D&>(rCandidate));
break;
}
+ case PRIMITIVE2D_ID_SVGLINEARGRADIENTPRIMITIVE2D:
+ {
+ processSvgLinearGradientPrimitive2D(
+ static_cast<const primitive2d::SvgLinearGradientPrimitive2D&>(rCandidate));
+ break;
+ }
+ case PRIMITIVE2D_ID_SVGRADIALGRADIENTPRIMITIVE2D:
+ {
+ processSvgRadialGradientPrimitive2D(
+ static_cast<const primitive2d::SvgRadialGradientPrimitive2D&>(rCandidate));
+ break;
+ }
// continue with decompose
default:
diff --git a/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx b/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx
index e63e1df96507..ff5ae8df2eac 100644
--- a/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx
@@ -100,7 +100,6 @@ namespace drawinglayer::primitive2d
/// how to spread
SpreadMethod maSpreadMethod;
- bool mbPreconditionsChecked : 1;
bool mbCreatesContent : 1;
bool mbSingleEntry : 1;
bool mbFullyOpaque : 1;
@@ -137,13 +136,14 @@ namespace drawinglayer::primitive2d
Primitive2DContainer aTargetOpacity,
const basegfx::B2DHomMatrix& rUnitGradientToObject,
bool bInvert = false) const;
- bool getCreatesContent() const { return mbCreatesContent; }
- bool getSingleEntry() const { return mbSingleEntry; }
+
void setSingleEntry() { mbSingleEntry = true; }
- bool getPreconditionsChecked() const { return mbPreconditionsChecked; }
bool getFullyOpaque() const { return mbFullyOpaque; }
public:
+ bool getCreatesContent() const { return mbCreatesContent; }
+ bool getSingleEntry() const { return mbSingleEntry; }
+
/// constructor
SvgGradientHelper(
basegfx::B2DHomMatrix aGradientTransform,
@@ -164,6 +164,9 @@ namespace drawinglayer::primitive2d
/// compare operator
bool operator==(const SvgGradientHelper& rSvgGradientHelper) const;
+
+ /// create transformation from UnitGrandient to ObjectTransform
+ virtual basegfx::B2DHomMatrix createUnitGradientToObjectTransformation() const = 0;
};
/// the basic linear gradient primitive
@@ -209,6 +212,9 @@ namespace drawinglayer::primitive2d
/// provide unique ID
virtual sal_uInt32 getPrimitive2DID() const override;
+
+ /// create transformation from UnitGrandient to ObjectTransform
+ virtual basegfx::B2DHomMatrix createUnitGradientToObjectTransformation() const override;
};
/// the basic radial gradient primitive
@@ -220,11 +226,8 @@ namespace drawinglayer::primitive2d
/// Focal only used when focal is set at all, see constructors
basegfx::B2DPoint maFocal;
- basegfx::B2DVector maFocalVector;
double maFocalLength;
- bool mbFocalSet : 1;
-
/// local helpers
virtual void createAtom(
Primitive2DContainer& rTargetColor,
@@ -254,7 +257,7 @@ namespace drawinglayer::primitive2d
/// data read access
double getRadius() const { return mfRadius; }
const basegfx::B2DPoint& getFocal() const { return maFocal; }
- bool isFocalSet() const { return mbFocalSet; }
+ bool isFocalSet() const { return !maFocal.equal(getStart()); }
/// compare operator
virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
@@ -264,6 +267,9 @@ namespace drawinglayer::primitive2d
/// provide unique ID
virtual sal_uInt32 getPrimitive2DID() const override;
+
+ /// create transformation from UnitGrandient to ObjectTransform
+ virtual basegfx::B2DHomMatrix createUnitGradientToObjectTransformation() const override;
};
// SvgLinearAtomPrimitive2D class
diff --git a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
index 56281bd0cd32..02a49842c512 100644
--- a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
+++ b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
@@ -43,6 +43,9 @@ class BitmapAlphaPrimitive2D;
class TextSimplePortionPrimitive2D;
class TextDecoratedPortionPrimitive2D;
class TextLayouterDevice;
+class SvgLinearGradientPrimitive2D;
+class SvgRadialGradientPrimitive2D;
+class SvgGradientHelper;
}
namespace basegfx
@@ -138,6 +141,13 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : pub
const basegfx::B2DHomMatrix* pOptionalObjectTransform = nullptr,
const basegfx::BColor* pReplacementColor = nullptr);
+ // support for SVG gradients
+ void processSvgLinearGradientPrimitive2D(
+ const primitive2d::SvgLinearGradientPrimitive2D& rCandidate);
+ void processSvgRadialGradientPrimitive2D(
+ const primitive2d::SvgRadialGradientPrimitive2D& rCandidate);
+ bool handleSvgGradientHelper(const primitive2d::SvgGradientHelper& rCandidate);
+
/* the local processor for BasePrimitive2D-Implementation based primitives,
called from the common process()-implementation
*/