diff options
-rw-r--r-- | basegfx/source/color/bcolormodifier.cxx | 74 | ||||
-rw-r--r-- | drawinglayer/source/tools/primitive2dxmldump.cxx | 12 | ||||
-rw-r--r-- | include/basegfx/color/bcolormodifier.hxx | 40 | ||||
-rw-r--r-- | svgio/inc/svgfecolormatrixnode.hxx | 6 | ||||
-rw-r--r-- | svgio/inc/svgtoken.hxx | 1 | ||||
-rw-r--r-- | svgio/qa/cppunit/SvgImportTest.cxx | 21 | ||||
-rw-r--r-- | svgio/qa/cppunit/data/filterSaturate.svg | 11 | ||||
-rw-r--r-- | svgio/source/svgreader/svgfecolormatrixnode.cxx | 29 | ||||
-rw-r--r-- | svgio/source/svgreader/svgtoken.cxx | 2 |
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 }, |