summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basegfx/source/color/bcolormodifier.cxx74
-rw-r--r--drawinglayer/source/tools/primitive2dxmldump.cxx12
-rw-r--r--include/basegfx/color/bcolormodifier.hxx40
-rw-r--r--svgio/inc/svgfecolormatrixnode.hxx6
-rw-r--r--svgio/inc/svgtoken.hxx1
-rw-r--r--svgio/qa/cppunit/SvgImportTest.cxx21
-rw-r--r--svgio/qa/cppunit/data/filterSaturate.svg11
-rw-r--r--svgio/source/svgreader/svgfecolormatrixnode.cxx29
-rw-r--r--svgio/source/svgreader/svgtoken.cxx2
9 files changed, 183 insertions, 13 deletions
diff --git a/basegfx/source/color/bcolormodifier.cxx b/basegfx/source/color/bcolormodifier.cxx
index f27ffcc9aaf0..2067257015b4 100644
--- a/basegfx/source/color/bcolormodifier.cxx
+++ b/basegfx/source/color/bcolormodifier.cxx
@@ -45,6 +45,11 @@ namespace basegfx
return ::basegfx::BColor(fLuminance, fLuminance, fLuminance);
}
+ OUString BColorModifier_gray::getModifierName() const
+ {
+ return "gray";
+ }
+
BColorModifier_invert::~BColorModifier_invert()
{
}
@@ -59,6 +64,11 @@ namespace basegfx
return ::basegfx::BColor(1.0 - aSourceColor.getRed(), 1.0 - aSourceColor.getGreen(), 1.0 - aSourceColor.getBlue());
}
+ OUString BColorModifier_invert::getModifierName() const
+ {
+ return "invert";
+ }
+
BColorModifier_luminance_to_alpha::~BColorModifier_luminance_to_alpha()
{
}
@@ -75,6 +85,11 @@ namespace basegfx
return ::basegfx::BColor(fAlpha, fAlpha, fAlpha);
}
+ OUString BColorModifier_luminance_to_alpha::getModifierName() const
+ {
+ return "luminance_to_alpha";
+ }
+
BColorModifier_replace::~BColorModifier_replace()
{
}
@@ -96,6 +111,11 @@ namespace basegfx
return maBColor;
}
+ OUString BColorModifier_replace::getModifierName() const
+ {
+ return "replace";
+ }
+
BColorModifier_interpolate::~BColorModifier_interpolate()
{
}
@@ -117,6 +137,40 @@ namespace basegfx
return interpolate(maBColor, aSourceColor, mfValue);
}
+ OUString BColorModifier_interpolate::getModifierName() const
+ {
+ return "interpolate";
+ }
+
+ BColorModifier_saturate::~BColorModifier_saturate()
+ {
+ }
+
+ bool BColorModifier_saturate::operator==(const BColorModifier& rCompare) const
+ {
+ const BColorModifier_saturate* pCompare = dynamic_cast< const BColorModifier_saturate* >(&rCompare);
+
+ if(!pCompare)
+ {
+ return false;
+ }
+
+ return mfValue == pCompare->mfValue;
+ }
+
+ ::basegfx::BColor BColorModifier_saturate::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
+ {
+ return basegfx::BColor(
+ (0.213 + 0.787 * mfValue) * aSourceColor.getRed() + (0.715 - 0.715 * mfValue) * aSourceColor.getGreen() + (0.072 - 0.072 * mfValue) * aSourceColor.getBlue(),
+ (0.213 - 0.213 * mfValue) * aSourceColor.getRed() + (0.715 + 0.285 * mfValue) * aSourceColor.getGreen() + (0.072 - 0.072 * mfValue) * aSourceColor.getBlue(),
+ (0.213 - 0.213 * mfValue) * aSourceColor.getRed() + (0.715 - 0.715 * mfValue) * aSourceColor.getGreen() + (0.072 + 0.928 * mfValue) * aSourceColor.getBlue());
+ }
+
+ OUString BColorModifier_saturate::getModifierName() const
+ {
+ return "saturate";
+ }
+
BColorModifier_black_and_white::~BColorModifier_black_and_white()
{
}
@@ -147,6 +201,11 @@ namespace basegfx
}
}
+ OUString BColorModifier_black_and_white::getModifierName() const
+ {
+ return "black_and_white";
+ }
+
BColorModifier_gamma::BColorModifier_gamma(double fValue)
: mfValue(fValue),
mfInvValue(fValue),
@@ -193,6 +252,11 @@ namespace basegfx
}
}
+ OUString BColorModifier_gamma::getModifierName() const
+ {
+ return "gamma";
+ }
+
BColorModifier_RGBLuminanceContrast::BColorModifier_RGBLuminanceContrast(double fRed, double fGreen, double fBlue, double fLuminance, double fContrast)
: mfRed(std::clamp(fRed, -1.0, 1.0)),
mfGreen(std::clamp(fGreen, -1.0, 1.0)),
@@ -270,6 +334,11 @@ namespace basegfx
}
}
+ OUString BColorModifier_RGBLuminanceContrast::getModifierName() const
+ {
+ return "RGBLuminanceContrast";
+ }
+
BColorModifier_randomize::BColorModifier_randomize(double fRandomPart)
: mfRandomPart(fRandomPart)
{
@@ -321,6 +390,11 @@ namespace basegfx
comphelper::rng::uniform_real_distribution(0.0, nextafter(mfRandomPart, DBL_MAX)));
}
+ OUString BColorModifier_randomize::getModifierName() const
+ {
+ return "randomize";
+ }
+
::basegfx::BColor BColorModifierStack::getModifiedColor(const ::basegfx::BColor& rSource) const
{
if(maBColorModifiers.empty())
diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx
index 7edb5bce5c89..37ea828a6fbb 100644
--- a/drawinglayer/source/tools/primitive2dxmldump.cxx
+++ b/drawinglayer/source/tools/primitive2dxmldump.cxx
@@ -38,6 +38,7 @@
#include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
#include <drawinglayer/primitive2d/sceneprimitive2d.hxx>
#include <drawinglayer/geometry/viewinformation2d.hxx>
#include <drawinglayer/attribute/lineattribute.hxx>
@@ -1127,11 +1128,14 @@ void Primitive2dXmlDump::decomposeAndWrite(
case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D:
{
// ModifiedColorPrimitive2D.
+ const ModifiedColorPrimitive2D& rModifiedColorPrimitive2D
+ = dynamic_cast<const ModifiedColorPrimitive2D&>(*pBasePrimitive);
rWriter.startElement("modifiedColor");
- drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer;
- pBasePrimitive->get2DDecomposition(aPrimitiveContainer,
- drawinglayer::geometry::ViewInformation2D());
- decomposeAndWrite(aPrimitiveContainer, rWriter);
+ const basegfx::BColorModifierSharedPtr& aColorModifier
+ = rModifiedColorPrimitive2D.getColorModifier();
+ rWriter.attribute("modifier", aColorModifier->getModifierName());
+
+ decomposeAndWrite(rModifiedColorPrimitive2D.getChildren(), rWriter);
rWriter.endElement();
break;
}
diff --git a/include/basegfx/color/bcolormodifier.hxx b/include/basegfx/color/bcolormodifier.hxx
index 911d74289a17..28ab7487eec3 100644
--- a/include/basegfx/color/bcolormodifier.hxx
+++ b/include/basegfx/color/bcolormodifier.hxx
@@ -22,6 +22,7 @@
#include <config_options.h>
#include <basegfx/basegfxdllapi.h>
#include <basegfx/color/bcolor.hxx>
+#include <rtl/ustring.hxx>
#include <osl/diagnose.h>
@@ -80,6 +81,8 @@ namespace basegfx
// compute modified color
virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const = 0;
+
+ virtual OUString getModifierName() const = 0;
};
/** convert color to gray
@@ -98,6 +101,7 @@ namespace basegfx
// compute modified color
SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
};
/** invert color
@@ -118,6 +122,7 @@ namespace basegfx
// compute modified color
SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
};
/** convert to alpha based on luminance
@@ -142,6 +147,7 @@ namespace basegfx
// compute modified color
SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
};
/** replace color
@@ -171,6 +177,7 @@ namespace basegfx
// compute modified color
SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
};
/** interpolate color
@@ -200,6 +207,35 @@ namespace basegfx
// compute modified color
SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
+ };
+
+ /** Apply saturation
+ This derivation is used for the svg importer and does exactly what SVG
+ defines for this needed case.
+
+ See:
+ https://www.w3.org/TR/filter-effects/#elementdef-fecolormatrix
+ */
+ class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_saturate final : public BColorModifier
+ {
+ private:
+ double mfValue;
+
+ public:
+ BColorModifier_saturate(double fValue)
+ : mfValue(fValue)
+ {
+ }
+
+ virtual ~BColorModifier_saturate() override;
+
+ // compare operator
+ SAL_DLLPRIVATE virtual bool operator==(const BColorModifier& rCompare) const override;
+
+ // compute modified color
+ SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
};
/** convert color to black and white
@@ -225,6 +261,7 @@ namespace basegfx
// compute modified color
SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
};
/** gamma correction
@@ -252,6 +289,7 @@ namespace basegfx
// compute modified color
virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
};
/** Red, Green, Blue, Luminance and Contrast correction
@@ -288,6 +326,7 @@ namespace basegfx
// compute modified color
SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
};
/** mix a part of the original color with randomized color (mainly for debug visualizations)
@@ -309,6 +348,7 @@ namespace basegfx
// compute modified color
SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override;
+ SAL_DLLPRIVATE virtual OUString getModifierName() const override;
};
/// typedef to allow working with shared instances of BColorModifier
diff --git a/svgio/inc/svgfecolormatrixnode.hxx b/svgio/inc/svgfecolormatrixnode.hxx
index 7436f737b04c..631da8877372 100644
--- a/svgio/inc/svgfecolormatrixnode.hxx
+++ b/svgio/inc/svgfecolormatrixnode.hxx
@@ -25,16 +25,18 @@
namespace svgio::svgreader
{
-enum class Type
+enum class ColorType
{
None,
+ Saturate,
LuminanceToAlpha
};
class SvgFeColorMatrixNode final : public SvgNode
{
private:
- Type maType;
+ ColorType maType;
+ SvgNumber maValues;
public:
SvgFeColorMatrixNode(SvgDocument& rDocument, SvgNode* pParent);
diff --git a/svgio/inc/svgtoken.hxx b/svgio/inc/svgtoken.hxx
index 18c1a092c238..a28be73df50a 100644
--- a/svgio/inc/svgtoken.hxx
+++ b/svgio/inc/svgtoken.hxx
@@ -122,6 +122,7 @@ namespace svgio::svgreader
XMaxYMax,
Meet,
Slice,
+ Values,
// structural elements
Defs,
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx
index 559af49af695..bdfbfcccb911 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -153,17 +153,30 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf155819)
assertXPath(pDocument, "/primitive2D/transform/transform", 4);
}
+CPPUNIT_TEST_FIXTURE(Test, testFilterSaturate)
+{
+ Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/filterSaturate.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequence);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/modifiedColor", "modifier", "saturate");
+}
+
CPPUNIT_TEST_FIXTURE(Test, testFilterLuminanceToAlpha)
{
- Primitive2DSequence aSequenceTdf132246 = parseSvg(u"/svgio/qa/cppunit/data/filterLuminanceToAlpha.svg");
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf132246.getLength()));
+ Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/filterLuminanceToAlpha.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
drawinglayer::Primitive2dXmlDump dumper;
- xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceTdf132246);
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequence);
CPPUNIT_ASSERT (pDocument);
- assertXPath(pDocument, "/primitive2D/transform/modifiedColor");
+ assertXPath(pDocument, "/primitive2D/transform/modifiedColor", "modifier", "luminance_to_alpha");
}
CPPUNIT_TEST_FIXTURE(Test, testFilterFeGaussianBlur)
diff --git a/svgio/qa/cppunit/data/filterSaturate.svg b/svgio/qa/cppunit/data/filterSaturate.svg
new file mode 100644
index 000000000000..3fc1ab89f538
--- /dev/null
+++ b/svgio/qa/cppunit/data/filterSaturate.svg
@@ -0,0 +1,11 @@
+<svg
+ width="230"
+ height="120"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <filter id="saturate">
+ <feColorMatrix type="saturate" values="0.5"/>
+ </filter>
+ <circle cx="170" cy="60" r="50" fill="green" filter="url(#saturate)" />
+</svg>
+
diff --git a/svgio/source/svgreader/svgfecolormatrixnode.cxx b/svgio/source/svgreader/svgfecolormatrixnode.cxx
index fb53f1d5c503..2a02ddc3c0bd 100644
--- a/svgio/source/svgreader/svgfecolormatrixnode.cxx
+++ b/svgio/source/svgreader/svgfecolormatrixnode.cxx
@@ -25,7 +25,8 @@ namespace svgio::svgreader
{
SvgFeColorMatrixNode::SvgFeColorMatrixNode(SvgDocument& rDocument, SvgNode* pParent)
: SvgNode(SVGToken::FeColorMatrix, rDocument, pParent)
- , maType(Type::None)
+ , maType(ColorType::None)
+ , maValues(1.0)
{
}
@@ -43,8 +44,22 @@ void SvgFeColorMatrixNode::parseAttribute(const OUString& /*rTokenName*/, SVGTok
{
if (o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"luminanceToAlpha"))
{
- maType = Type::LuminanceToAlpha;
+ maType = ColorType::LuminanceToAlpha;
}
+ else if (o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"saturate"))
+ {
+ maType = ColorType::Saturate;
+ }
+ }
+ break;
+ }
+ case SVGToken::Values:
+ {
+ SvgNumber aNum;
+
+ if (readSingleNumber(aContent, aNum))
+ {
+ maValues = aNum;
}
break;
}
@@ -57,7 +72,7 @@ void SvgFeColorMatrixNode::parseAttribute(const OUString& /*rTokenName*/, SVGTok
void SvgFeColorMatrixNode::apply(drawinglayer::primitive2d::Primitive2DContainer& rTarget) const
{
- if (maType == Type::LuminanceToAlpha)
+ if (maType == ColorType::LuminanceToAlpha)
{
const drawinglayer::primitive2d::Primitive2DReference xRef(
new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
@@ -65,6 +80,14 @@ void SvgFeColorMatrixNode::apply(drawinglayer::primitive2d::Primitive2DContainer
std::make_shared<basegfx::BColorModifier_luminance_to_alpha>()));
rTarget = drawinglayer::primitive2d::Primitive2DContainer{ xRef };
}
+ else if (maType == ColorType::Saturate)
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
+ std::move(rTarget),
+ std::make_shared<basegfx::BColorModifier_saturate>(maValues.getNumber())));
+ rTarget = drawinglayer::primitive2d::Primitive2DContainer{ xRef };
+ }
}
} // end of namespace svgio::svgreader
diff --git a/svgio/source/svgreader/svgtoken.cxx b/svgio/source/svgreader/svgtoken.cxx
index 8228689606bf..09ed13459b2e 100644
--- a/svgio/source/svgreader/svgtoken.cxx
+++ b/svgio/source/svgreader/svgtoken.cxx
@@ -113,6 +113,7 @@ namespace svgio::svgreader
const char aSVGStrXMaxYMax[] = "xMaxYMax";
const char aSVGStrMeet[] = "meet";
const char aSVGStrSlice[] = "slice";
+ const char aSVGStrValues[] = "values";
const char aSVGStrDefs[] = "defs";
const char aSVGStrG[] = "g";
@@ -265,6 +266,7 @@ namespace svgio::svgreader
{ aSVGStrXMaxYMax, SVGToken::XMaxYMax },
{ aSVGStrMeet, SVGToken::Meet },
{ aSVGStrSlice, SVGToken::Slice },
+ { aSVGStrValues, SVGToken::Values },
{ aSVGStrDefs, SVGToken::Defs },
{ aSVGStrG, SVGToken::G },