diff options
author | Armin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de> | 2023-05-12 15:32:51 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2023-05-15 15:19:53 +0200 |
commit | 438f0752deaf7d6e6d9d1df381b64aca4628e944 (patch) | |
tree | f1907b25dad1cbf2604b16c657e11f5623c8b5b2 /drawinglayer | |
parent | efa965969c6d3dfe5745a535605a6b9a482a03bd (diff) |
MCGR: consolidations/cleanups for changes so far
Change-Id: I85cf40e4803b0485bb40349d8e81adc8123666c4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151706
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'drawinglayer')
-rw-r--r-- | drawinglayer/inc/texture/texture.hxx | 21 | ||||
-rw-r--r-- | drawinglayer/qa/unit/vclpixelprocessor2d.cxx | 61 | ||||
-rw-r--r-- | drawinglayer/source/attribute/fillgradientattribute.cxx | 26 | ||||
-rw-r--r-- | drawinglayer/source/primitive3d/textureprimitive3d.cxx | 6 | ||||
-rw-r--r-- | drawinglayer/source/processor3d/defaultprocessor3d.cxx | 6 | ||||
-rw-r--r-- | drawinglayer/source/texture/texture.cxx | 146 | ||||
-rw-r--r-- | drawinglayer/source/tools/wmfemfhelper.cxx | 20 |
7 files changed, 170 insertions, 116 deletions
diff --git a/drawinglayer/inc/texture/texture.hxx b/drawinglayer/inc/texture/texture.hxx index 01d3ec5c64c5..5128a30cf2a8 100644 --- a/drawinglayer/inc/texture/texture.hxx +++ b/drawinglayer/inc/texture/texture.hxx @@ -49,21 +49,18 @@ namespace drawinglayer::texture basegfx::ODFGradientInfo maGradientInfo; basegfx::B2DRange maDefinitionRange; sal_uInt32 mnRequestedSteps; - basegfx::ColorStops mnColorStops; + basegfx::BColorStops mnColorStops; double mfBorder; // provide a single buffer entry used for gradient texture // mapping, see ::modifyBColor implementations - mutable basegfx::ColorStopRange maLastColorStopRange; - - // check if we need last-ColorStop-correction - bool checkPenultimate(); + mutable basegfx::BColorStops::BColorStopRange maLastColorStopRange; public: GeoTexSvxGradient( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder); virtual ~GeoTexSvxGradient() override; @@ -86,7 +83,7 @@ namespace drawinglayer::texture const basegfx::B2DRange& rDefinitionRange, const basegfx::B2DRange& rOutputRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fAngle); virtual ~GeoTexSvxGradientLinear() override; @@ -106,7 +103,7 @@ namespace drawinglayer::texture const basegfx::B2DRange& rDefinitionRange, const basegfx::B2DRange& rOutputRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fAngle); virtual ~GeoTexSvxGradientAxial() override; @@ -122,7 +119,7 @@ namespace drawinglayer::texture GeoTexSvxGradientRadial( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fOffsetX, double fOffsetY); @@ -139,7 +136,7 @@ namespace drawinglayer::texture GeoTexSvxGradientElliptical( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fOffsetX, double fOffsetY, @@ -157,7 +154,7 @@ namespace drawinglayer::texture GeoTexSvxGradientSquare( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fOffsetX, double fOffsetY, @@ -175,7 +172,7 @@ namespace drawinglayer::texture GeoTexSvxGradientRect( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fOffsetX, double fOffsetY, diff --git a/drawinglayer/qa/unit/vclpixelprocessor2d.cxx b/drawinglayer/qa/unit/vclpixelprocessor2d.cxx index 6ccf1e7c55ab..7f59e7e3edd0 100644 --- a/drawinglayer/qa/unit/vclpixelprocessor2d.cxx +++ b/drawinglayer/qa/unit/vclpixelprocessor2d.cxx @@ -16,8 +16,10 @@ #include <tools/stream.hxx> #include <drawinglayer/geometry/viewinformation2d.hxx> #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> #include <drawinglayer/processor2d/baseprocessor2d.hxx> #include <drawinglayer/processor2d/processor2dtools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/utils/gradienttools.hxx> using namespace drawinglayer; @@ -58,16 +60,59 @@ public: processor2d::createProcessor2DFromOutputDevice(*device, view)); CPPUNIT_ASSERT(processor); + // I stumbled over this when hunting another problem, but I have to correct + // this: This test does test something that is not supported. It seems to be + // based on the *misunderstanding* that in the version of the constructor of + // FillGradientPrimitive2D (and similar others) with two ranges the 2nd + // B2DRange parameter 'OutputRange' is a 'clipping' parameter. This is *not* + // the case --- it is in fact the *contrary*, it is there to *extend* the + // usual definition/paintRange of a gradient: + // It was originally needed to correctly display TextFrames (TF) in Writer: If you + // have a TF in SW filled with a gradient and that TF has sub-frames, it inhertits + // the gradient fill. Since you can freely move those sub-TFs even outside the + // parent TF there has to be a way to not only paint gradients in ther definition + // range (classical, all DrawObjects do that), but extended from that. This is + // needed e.g. for linerar gradients, but - dependent of e.g. the center settings - + // also for all other ones, all can have geometry 'outside' the DefinitionRange. + // This is now also used in various other locations which is proof that this is + // useful and needed. It is possible to see that basic history/reason for this + // parameter by following the git history and why and under which circumstances + // that parameter was originally added. Other hints are: It is *not* named + // 'ClipRange'. Using a B2DRange to define a ClipRange topology would be bad due + // to not being transformable, a PolyPolygon would be used in that case. Using as + // clipping mechanism would offer a 2nd pinciple to add clipping for primitives + // besides MaskPrimitive2D - always bad style in a sub-system. A quick look + // on it's usages gives hints, too. + // This means that when defining a outputRange tat resides completely *inside* + // the definitionRange *no change* at all is done by definition since this does + // not *extend* the target area of the gradient paint region at all. If an + // implementation does clip and limit output to 'outputRange' that should do no + // harm, but is not the expected/reliable way to paint primitives clipped. + // That's why all DrawObjects with gradient fill (and other fills do the same) + // embed the fill that is defined for a range (usually the BoundRange of a + // PolyPolygon) in a MaskPrimitive2D defined by the outline PolyPolygon of the + // shape. Nothing speaks against renderers detecting that combination and do + // something optimized if they want to, especially SDPRs, but this is not + // required. The standard embedded clipping of the mplementations of the + // MaskPrimitive2D do the right thing. + // This test intends to paint the lower part of a gradient, so define the + // gradient for the full target range and embed it to a MaskPrimitive2D + // defining the lower part of that area to do that. + basegfx::B2DRange definitionRange(0, 0, 100, 200); basegfx::B2DRange outputRange(0, 100, 100, 200); // Paint only lower half of the gradient. - attribute::FillGradientAttribute attributes( - css::awt::GradientStyle_LINEAR, 0, 0, 0, 0, - basegfx::utils::createColorStopsFromStartEndColor(COL_WHITE.getBColor(), - COL_BLACK.getBColor())); - rtl::Reference<primitive2d::FillGradientPrimitive2D> gradientPrimitive( - new primitive2d::FillGradientPrimitive2D(outputRange, definitionRange, attributes)); - primitive2d::Primitive2DContainer primitives; - primitives.push_back(primitive2d::Primitive2DReference(gradientPrimitive)); + + const primitive2d::Primitive2DContainer primitives{ + rtl::Reference<primitive2d::MaskPrimitive2D>(new primitive2d::MaskPrimitive2D( + basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(outputRange)), + primitive2d::Primitive2DContainer{ + rtl::Reference<primitive2d::FillGradientPrimitive2D>( + new primitive2d::FillGradientPrimitive2D( + definitionRange, attribute::FillGradientAttribute( + css::awt::GradientStyle_LINEAR, 0, 0, 0, 0, + basegfx::BColorStops(COL_WHITE.getBColor(), + COL_BLACK.getBColor())))) })) + }; processor->process(primitives); exportDevice("test-tdf139000.png", device); diff --git a/drawinglayer/source/attribute/fillgradientattribute.cxx b/drawinglayer/source/attribute/fillgradientattribute.cxx index 0233195113af..e02fdd4a5dad 100644 --- a/drawinglayer/source/attribute/fillgradientattribute.cxx +++ b/drawinglayer/source/attribute/fillgradientattribute.cxx @@ -30,7 +30,7 @@ namespace drawinglayer::attribute double mfOffsetX; double mfOffsetY; double mfAngle; - basegfx::ColorStops maColorStops; + basegfx::BColorStops maColorStops; css::awt::GradientStyle meStyle; sal_uInt16 mnSteps; @@ -40,7 +40,7 @@ namespace drawinglayer::attribute double fOffsetX, double fOffsetY, double fAngle, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, sal_uInt16 nSteps) : mfBorder(fBorder), mfOffsetX(fOffsetX), @@ -57,7 +57,7 @@ namespace drawinglayer::attribute // This is what the usages of this in primitives need. // Since FillGradientAttribute is read-only doing this // once here in the constructor is sufficient - basegfx::utils::sortAndCorrectColorStops(maColorStops); + maColorStops.sortAndCorrect(); // sortAndCorrectColorStops is rigid and can return // an empty result. To keep things simple, add a single @@ -87,18 +87,9 @@ namespace drawinglayer::attribute double getOffsetX() const { return mfOffsetX; } double getOffsetY() const { return mfOffsetY; } double getAngle() const { return mfAngle; } - const basegfx::ColorStops& getColorStops() const { return maColorStops; } + const basegfx::BColorStops& getColorStops() const { return maColorStops; } sal_uInt16 getSteps() const { return mnSteps; } - bool hasSingleColor() const - { - // No entry (should not happen, see comments for startColor above) - // or single entry -> no gradient. - // No need to check for all-the-same color since this is checked/done - // in the constructor already, see there - return maColorStops.size() < 2; - } - bool operator==(const ImpFillGradientAttribute& rCandidate) const { return (getStyle() == rCandidate.getStyle() @@ -126,7 +117,7 @@ namespace drawinglayer::attribute double fOffsetX, double fOffsetY, double fAngle, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, sal_uInt16 nSteps) : mpFillGradientAttribute(ImpFillGradientAttribute( eStyle, fBorder, fOffsetX, fOffsetY, fAngle, rColorStops, nSteps)) @@ -149,11 +140,6 @@ namespace drawinglayer::attribute return mpFillGradientAttribute.same_object(theGlobalDefault()); } - bool FillGradientAttribute::hasSingleColor() const - { - return mpFillGradientAttribute->hasSingleColor(); - } - // MCGR: Check if rendering cannot be handled by old vcl stuff bool FillGradientAttribute::cannotBeHandledByVCL() const { @@ -202,7 +188,7 @@ namespace drawinglayer::attribute return rCandidate.mpFillGradientAttribute == mpFillGradientAttribute; } - const basegfx::ColorStops& FillGradientAttribute::getColorStops() const + const basegfx::BColorStops& FillGradientAttribute::getColorStops() const { return mpFillGradientAttribute->getColorStops(); } diff --git a/drawinglayer/source/primitive3d/textureprimitive3d.cxx b/drawinglayer/source/primitive3d/textureprimitive3d.cxx index ebae584e9dbf..ceeca0489487 100644 --- a/drawinglayer/source/primitive3d/textureprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/textureprimitive3d.cxx @@ -95,9 +95,9 @@ namespace drawinglayer::primitive3d const basegfx::BColor aGray(getTransparence(), getTransparence(), getTransparence()); // create ColorStops with StartColor == EndColor == aGray - const basegfx::ColorStops aColorStops { - basegfx::ColorStop(0.0, aGray), - basegfx::ColorStop(1.0, aGray) }; + const basegfx::BColorStops aColorStops { + basegfx::BColorStop(0.0, aGray), + basegfx::BColorStop(1.0, aGray) }; const attribute::FillGradientAttribute aFillGradient(css::awt::GradientStyle_LINEAR, 0.0, 0.0, 0.0, 0.0, aColorStops); const Primitive3DReference xRef(new TransparenceTexturePrimitive3D(aFillGradient, getChildren(), getTextureSize())); diff --git a/drawinglayer/source/processor3d/defaultprocessor3d.cxx b/drawinglayer/source/processor3d/defaultprocessor3d.cxx index 20d81871dbd7..0d07b0a5c343 100644 --- a/drawinglayer/source/processor3d/defaultprocessor3d.cxx +++ b/drawinglayer/source/processor3d/defaultprocessor3d.cxx @@ -61,8 +61,9 @@ namespace drawinglayer::processor3d const basegfx::B2DRange aOutlineRange(0.0, 0.0, rPrimitive.getTextureSize().getX(), rPrimitive.getTextureSize().getY()); const css::awt::GradientStyle aGradientStyle(rFillGradient.getStyle()); std::shared_ptr< texture::GeoTexSvx > pNewTex; + basegfx::BColor aSingleColor; - if(!rFillGradient.hasSingleColor()) + if (!rFillGradient.getColorStops().isSingleColor(aSingleColor)) { switch(aGradientStyle) { @@ -147,8 +148,7 @@ namespace drawinglayer::processor3d else { // only one color, so no real gradient -> use simple texture - const basegfx::BColor aStart(rFillGradient.getColorStops().front().getStopColor()); - pNewTex = std::make_shared<texture::GeoTexSvxMono>(aStart, 1.0 - aStart.luminance()); + pNewTex = std::make_shared<texture::GeoTexSvxMono>(aSingleColor, 1.0 - aSingleColor.luminance()); mbSimpleTextureActive = true; } diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx index eb9df6469225..5176838d610e 100644 --- a/drawinglayer/source/texture/texture.cxx +++ b/drawinglayer/source/texture/texture.cxx @@ -73,7 +73,7 @@ namespace drawinglayer::texture GeoTexSvxGradient::GeoTexSvxGradient( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder) : maDefinitionRange(rDefinitionRange) , mnRequestedSteps(nRequestedSteps) @@ -99,47 +99,11 @@ namespace drawinglayer::texture && mfBorder == pCompare->mfBorder); } - bool GeoTexSvxGradient::checkPenultimate() - { - // not needed when no ColorStops - if (mnColorStops.empty()) - return false; - - // not needed when last ColorStop at the end or outside - if (basegfx::fTools::moreOrEqual(mnColorStops.back().getStopOffset(), 1.0)) - return false; - - // get penultimate entry - const auto penultimate(mnColorStops.rbegin() + 1); - - // if there is none, we need no correction and are done - if (penultimate == mnColorStops.rend()) - return false; - - // not needed when the last two ColorStops have different offset, then - // a visible range will be processed already - if (!basegfx::fTools::equal(mnColorStops.back().getStopOffset(), penultimate->getStopOffset())) - return false; - - // not needed when the last two ColorStops have the same Color, then the - // range before solves the problem - if (mnColorStops.back().getStopColor() == penultimate->getStopColor()) - return false; - - // Here we need to temporarily add a ColorStop entry with the - // same color as the last entry to correctly 'close' the - // created gradient geometry. - // The simplest way is to temporarily add an entry to the local - // ColorStops for this at 1.0 (using same color) - mnColorStops.emplace_back(1.0, mnColorStops.back().getStopColor()); - return true; - } - GeoTexSvxGradientLinear::GeoTexSvxGradientLinear( const basegfx::B2DRange& rDefinitionRange, const basegfx::B2DRange& rOutputRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fAngle) : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorStops, fBorder) @@ -180,7 +144,17 @@ namespace drawinglayer::texture return; // check if we need last-ColorStop-correction - const bool bPenultimateUsed(checkPenultimate()); + const bool bPenultimateUsed(mnColorStops.checkPenultimate()); + + if (bPenultimateUsed) + { + // Here we need to temporarily add a ColorStop entry with the + // same color as the last entry to correctly 'close' the + // created gradient geometry. + // The simplest way is to temporarily add an entry to the local + // ColorStops for this at 1.0 (using same color) + mnColorStops.emplace_back(1.0, mnColorStops.back().getStopColor()); + } // prepare unit range transform basegfx::B2DHomMatrix aPattern; @@ -200,7 +174,7 @@ namespace drawinglayer::texture const double fOffsetStart(cs_l->getStopOffset()); const double fOffsetEnd(cs_r->getStopOffset()); - // same offset, empty ColorStopRange, continue with next step + // same offset, empty BColorStopRange, continue with next step if (basegfx::fTools::equal(fOffsetStart, fOffsetEnd)) continue; @@ -249,7 +223,10 @@ namespace drawinglayer::texture } if (bPenultimateUsed) + { + // correct temporary change mnColorStops.pop_back(); + } } void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const @@ -267,14 +244,14 @@ namespace drawinglayer::texture // texture-back-transform X/Y -> t [0.0..1.0] and determine color const double fScaler(basegfx::utils::getLinearGradientAlpha(rUV, maGradientInfo)); - rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps, maLastColorStopRange); + rBColor = mnColorStops.getInterpolatedBColor(fScaler, mnRequestedSteps, maLastColorStopRange); } GeoTexSvxGradientAxial::GeoTexSvxGradientAxial( const basegfx::B2DRange& rDefinitionRange, const basegfx::B2DRange& rOutputRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fAngle) : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorStops, fBorder) @@ -285,7 +262,7 @@ namespace drawinglayer::texture // with the other gradients. Either stay 'thinking reverse' for the // rest of time or adapt it here and go in same order as the other five, // so unifications/tooling will be possible - basegfx::utils::reverseColorStops(mnColorStops); + mnColorStops.reverseColorStops(); maGradientInfo = basegfx::utils::createAxialODFGradientInfo( rDefinitionRange, @@ -319,7 +296,13 @@ namespace drawinglayer::texture return; // check if we need last-ColorStop-correction - const bool bPenultimateUsed(checkPenultimate()); + const bool bPenultimateUsed(mnColorStops.checkPenultimate()); + + if (bPenultimateUsed) + { + // temporarily add a ColorStop entry + mnColorStops.emplace_back(1.0, mnColorStops.back().getStopColor()); + } // prepare unit range transform basegfx::B2DHomMatrix aPattern; @@ -339,7 +322,7 @@ namespace drawinglayer::texture const double fOffsetStart(cs_l->getStopOffset()); const double fOffsetEnd(cs_r->getStopOffset()); - // same offset, empty ColorStopRange, continue with next step + // same offset, empty BColorStopRange, continue with next step if (basegfx::fTools::equal(fOffsetStart, fOffsetEnd)) continue; @@ -373,7 +356,10 @@ namespace drawinglayer::texture } if (bPenultimateUsed) + { + // correct temporary change mnColorStops.pop_back(); + } } void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const @@ -394,14 +380,14 @@ namespace drawinglayer::texture const double fScaler(basegfx::utils::getAxialGradientAlpha(rUV, maGradientInfo)); // we use the reverse ColorSteps here, so mirror scaler value - rBColor = basegfx::utils::modifyBColor(mnColorStops, 1.0 - fScaler, mnRequestedSteps, maLastColorStopRange); + rBColor = mnColorStops.getInterpolatedBColor(1.0 - fScaler, mnRequestedSteps, maLastColorStopRange); } GeoTexSvxGradientRadial::GeoTexSvxGradientRadial( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fOffsetX, double fOffsetY) @@ -430,7 +416,13 @@ namespace drawinglayer::texture return; // check if we need last-ColorStop-correction - const bool bPenultimateUsed(checkPenultimate()); + const bool bPenultimateUsed(mnColorStops.checkPenultimate()); + + if (bPenultimateUsed) + { + // temporarily add a ColorStop entry + mnColorStops.emplace_back(1.0, mnColorStops.back().getStopColor()); + } // outer loop over ColorStops, each is from cs_l to cs_r for (auto cs_l(mnColorStops.begin()), cs_r(cs_l + 1); cs_r != mnColorStops.end(); cs_l++, cs_r++) @@ -439,7 +431,7 @@ namespace drawinglayer::texture const double fOffsetStart(cs_l->getStopOffset()); const double fOffsetEnd(cs_r->getStopOffset()); - // same offset, empty ColorStopRange, continue with next step + // same offset, empty BColorStopRange, continue with next step if (basegfx::fTools::equal(fOffsetStart, fOffsetEnd)) continue; @@ -468,7 +460,10 @@ namespace drawinglayer::texture } if (bPenultimateUsed) + { + // correct temporary change mnColorStops.pop_back(); + } } void GeoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const @@ -486,14 +481,14 @@ namespace drawinglayer::texture // texture-back-transform X/Y -> t [0.0..1.0] and determine color const double fScaler(basegfx::utils::getRadialGradientAlpha(rUV, maGradientInfo)); - rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps, maLastColorStopRange); + rBColor = mnColorStops.getInterpolatedBColor(fScaler, mnRequestedSteps, maLastColorStopRange); } GeoTexSvxGradientElliptical::GeoTexSvxGradientElliptical( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fOffsetX, double fOffsetY, @@ -524,7 +519,13 @@ namespace drawinglayer::texture return; // check if we need last-ColorStop-correction - const bool bPenultimateUsed(checkPenultimate()); + const bool bPenultimateUsed(mnColorStops.checkPenultimate()); + + if (bPenultimateUsed) + { + // temporarily add a ColorStop entry + mnColorStops.emplace_back(1.0, mnColorStops.back().getStopColor()); + } // prepare vars dependent on aspect ratio const double fAR(maGradientInfo.getAspectRatio()); @@ -537,7 +538,7 @@ namespace drawinglayer::texture const double fOffsetStart(cs_l->getStopOffset()); const double fOffsetEnd(cs_r->getStopOffset()); - // same offset, empty ColorStopRange, continue with next step + // same offset, empty BColorStopRange, continue with next step if (basegfx::fTools::equal(fOffsetStart, fOffsetEnd)) continue; @@ -569,7 +570,10 @@ namespace drawinglayer::texture } if (bPenultimateUsed) + { + // correct temporary change mnColorStops.pop_back(); + } } void GeoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const @@ -587,14 +591,14 @@ namespace drawinglayer::texture // texture-back-transform X/Y -> t [0.0..1.0] and determine color const double fScaler(basegfx::utils::getEllipticalGradientAlpha(rUV, maGradientInfo)); - rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps, maLastColorStopRange); + rBColor = mnColorStops.getInterpolatedBColor(fScaler, mnRequestedSteps, maLastColorStopRange); } GeoTexSvxGradientSquare::GeoTexSvxGradientSquare( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fOffsetX, double fOffsetY, @@ -625,7 +629,13 @@ namespace drawinglayer::texture return; // check if we need last-ColorStop-correction - const bool bPenultimateUsed(checkPenultimate()); + const bool bPenultimateUsed(mnColorStops.checkPenultimate()); + + if (bPenultimateUsed) + { + // temporarily add a ColorStop entry + mnColorStops.emplace_back(1.0, mnColorStops.back().getStopColor()); + } // outer loop over ColorStops, each is from cs_l to cs_r for (auto cs_l(mnColorStops.begin()), cs_r(cs_l + 1); cs_r != mnColorStops.end(); cs_l++, cs_r++) @@ -634,7 +644,7 @@ namespace drawinglayer::texture const double fOffsetStart(cs_l->getStopOffset()); const double fOffsetEnd(cs_r->getStopOffset()); - // same offset, empty ColorStopRange, continue with next step + // same offset, empty BColorStopRange, continue with next step if (basegfx::fTools::equal(fOffsetStart, fOffsetEnd)) continue; @@ -663,7 +673,10 @@ namespace drawinglayer::texture } if (bPenultimateUsed) + { + // correct temporary change mnColorStops.pop_back(); + } } void GeoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const @@ -681,14 +694,14 @@ namespace drawinglayer::texture // texture-back-transform X/Y -> t [0.0..1.0] and determine color const double fScaler(basegfx::utils::getSquareGradientAlpha(rUV, maGradientInfo)); - rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps, maLastColorStopRange); + rBColor = mnColorStops.getInterpolatedBColor(fScaler, mnRequestedSteps, maLastColorStopRange); } GeoTexSvxGradientRect::GeoTexSvxGradientRect( const basegfx::B2DRange& rDefinitionRange, sal_uInt32 nRequestedSteps, - const basegfx::ColorStops& rColorStops, + const basegfx::BColorStops& rColorStops, double fBorder, double fOffsetX, double fOffsetY, @@ -719,7 +732,13 @@ namespace drawinglayer::texture return; // check if we need last-ColorStop-correction - const bool bPenultimateUsed(checkPenultimate()); + const bool bPenultimateUsed(mnColorStops.checkPenultimate()); + + if (bPenultimateUsed) + { + // temporarily add a ColorStop entry + mnColorStops.emplace_back(1.0, mnColorStops.back().getStopColor()); + } // prepare vars dependent on aspect ratio const double fAR(maGradientInfo.getAspectRatio()); @@ -732,7 +751,7 @@ namespace drawinglayer::texture const double fOffsetStart(cs_l->getStopOffset()); const double fOffsetEnd(cs_r->getStopOffset()); - // same offset, empty ColorStopRange, continue with next step + // same offset, empty BColorStopRange, continue with next step if (basegfx::fTools::equal(fOffsetStart, fOffsetEnd)) continue; @@ -764,7 +783,10 @@ namespace drawinglayer::texture } if (bPenultimateUsed) + { + // correct temporary change mnColorStops.pop_back(); + } } void GeoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const @@ -782,7 +804,7 @@ namespace drawinglayer::texture // texture-back-transform X/Y -> t [0.0..1.0] and determine color const double fScaler(basegfx::utils::getRectangularGradientAlpha(rUV, maGradientInfo)); - rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps, maLastColorStopRange); + rBColor = mnColorStops.getInterpolatedBColor(fScaler, mnRequestedSteps, maLastColorStopRange); } diff --git a/drawinglayer/source/tools/wmfemfhelper.cxx b/drawinglayer/source/tools/wmfemfhelper.cxx index 1b2b2d0a5abd..aa48149219f3 100644 --- a/drawinglayer/source/tools/wmfemfhelper.cxx +++ b/drawinglayer/source/tools/wmfemfhelper.cxx @@ -681,7 +681,7 @@ namespace wmfemfhelper static_cast<double>(rGradient.GetOfsX()) * 0.01, static_cast<double>(rGradient.GetOfsY()) * 0.01, toRadians(rGradient.GetAngle()), - basegfx::utils::createColorStopsFromStartEndColor(aStart, aEnd), + basegfx::BColorStops(aStart, aEnd), rGradient.GetSteps()); } @@ -882,11 +882,12 @@ namespace wmfemfhelper PropertyHolder const & rPropertyHolder) { drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient)); + basegfx::BColor aSingleColor; - if(aAttribute.hasSingleColor()) + if (aAttribute.getColorStops().isSingleColor(aSingleColor)) { // not really a gradient. Create filled rectangle - return CreateColorWallpaper(rRange, aAttribute.getColorStops().front().getStopColor(), rPropertyHolder); + return CreateColorWallpaper(rRange, aSingleColor, rPropertyHolder); } else { @@ -2052,8 +2053,9 @@ namespace wmfemfhelper const Gradient& rGradient = pA->GetGradient(); drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient)); basegfx::B2DPolyPolygon aOutline(basegfx::utils::createPolygonFromRect(aRange)); + basegfx::BColor aSingleColor; - if(aAttribute.hasSingleColor()) + if (aAttribute.getColorStops().isSingleColor(aSingleColor)) { // not really a gradient. Create filled rectangle createFillPrimitive( @@ -2762,14 +2764,15 @@ namespace wmfemfhelper // check if gradient is a real gradient const Gradient& rGradient = pA->GetGradient(); drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient)); + basegfx::BColor aSingleColor; - if(aAttribute.hasSingleColor()) + if (aAttribute.getColorStops().isSingleColor(aSingleColor)) { // not really a gradient; create UnifiedTransparencePrimitive2D rTargetHolders.Current().append( new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( std::move(xSubContent), - aAttribute.getColorStops().front().getStopColor().luminance())); + aSingleColor.luminance())); } else { @@ -2882,14 +2885,15 @@ namespace wmfemfhelper // get and check if gradient is a real gradient const Gradient& rGradient = pMetaGradientExAction->GetGradient(); drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient)); + basegfx::BColor aSingleColor; - if(aAttribute.hasSingleColor()) + if (aAttribute.getColorStops().isSingleColor(aSingleColor)) { // not really a gradient rTargetHolders.Current().append( new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( std::move(aPolyPolygon), - aAttribute.getColorStops().front().getStopColor())); + aSingleColor)); } else { |