diff options
-rw-r--r-- | basegfx/source/tools/gradienttools.cxx | 115 | ||||
-rw-r--r-- | drawinglayer/qa/unit/vclpixelprocessor2d.cxx | 5 | ||||
-rw-r--r-- | drawinglayer/source/attribute/fillgradientattribute.cxx | 116 | ||||
-rw-r--r-- | drawinglayer/source/primitive3d/textureprimitive3d.cxx | 9 | ||||
-rw-r--r-- | drawinglayer/source/texture/texture.cxx | 46 | ||||
-rw-r--r-- | drawinglayer/source/tools/wmfemfhelper.cxx | 8 | ||||
-rw-r--r-- | include/basegfx/utils/gradienttools.hxx | 31 | ||||
-rw-r--r-- | include/drawinglayer/attribute/fillgradientattribute.hxx | 21 | ||||
-rw-r--r-- | svx/source/sdr/primitive2d/sdrattributecreator.cxx | 45 | ||||
-rw-r--r-- | svx/source/xoutdev/xtabgrdt.cxx | 8 | ||||
-rw-r--r-- | sw/source/uibase/docvw/HeaderFooterWin.cxx | 7 | ||||
-rw-r--r-- | sw/source/uibase/docvw/ShadowOverlayObject.cxx | 20 |
12 files changed, 264 insertions, 167 deletions
diff --git a/basegfx/source/tools/gradienttools.cxx b/basegfx/source/tools/gradienttools.cxx index f35f91f5a79a..5743f71ad980 100644 --- a/basegfx/source/tools/gradienttools.cxx +++ b/basegfx/source/tools/gradienttools.cxx @@ -263,6 +263,121 @@ namespace basegfx namespace utils { + /* Tooling method to guarantee sort and correctness for + the given ColorSteps vector. + At return, the following conditions are guaranteed: + - contains no ColorSteps with offset < 0.0 (will + be removed) + - contains no ColorSteps with offset > 0.0 (will + be removed) + - contains no ColorSteps with identical offset + (will be removed, 1st one wins) + - will be sorted from lowest offset to highest + - if all colors are the same, the content will + be reducved to a single entry with offset 0.0 + (StartColor) + + Some more notes: + - It can happen that the result is empty + - It is allowed to have consecutive entries with + the same color, this represents single-color + regions inside the gradient + - A entry with 0.0 is not required or forced, so + no 'StartColor' is required on this level + - A entry with 1.0 is not required or forced, so + no 'EndColor' is required on this level + + All this is done in one run (sort + O(N)) without + creating a copy of the data in any form + */ + void sortAndCorrectColorSteps(ColorSteps& rColorSteps) + { + // no content, we are done + if (rColorSteps.empty()) + return; + + if (1 == rColorSteps.size()) + { + // no gradient at all, but preserve given color + // and force it to be the StartColor + rColorSteps[0] = ColorStep(0.0, rColorSteps[0].getColor()); + } + + // start with sorting the input data. Remember that + // this preserves the order of equal entries, where + // equal is defined here by offset (see use operator==) + std::sort(rColorSteps.begin(), rColorSteps.end()); + + // preapare status values + bool bSameColorInit(false); + bool bAllTheSameColor(true); + basegfx::BColor aFirstColor; + size_t write(0); + + // use the paradigm of a band machine with two heads, read + // and write with write <= read all the time. Step over the + // data using read and check for valid entry. If valid, decide + // how to keep it + for (size_t read(0); read < rColorSteps.size(); read++) + { + // get offset of entry at read position + const double rOff(rColorSteps[read].getOffset()); + + // step over < 0 values + if (basegfx::fTools::less(rOff, 0.0)) + continue; + + // step over > 1 values; even break, since all following + // entries will also be bigger due to being sorted, so done + if (basegfx::fTools::more(rOff, 1.0)) + break; + + // entry is valid value at read position + + // check/init for all-the-same color + if(bSameColorInit) + { + // already initialized, compare + bAllTheSameColor = bAllTheSameColor && aFirstColor == rColorSteps[read].getColor(); + } + else + { + // do initialize, remember 1st valid color + bSameColorInit = true; + aFirstColor = rColorSteps[read].getColor(); + } + + // copy if write target is empty (write at start) or when + // write target is different to read + if (0 == write || rOff != rColorSteps[write-1].getOffset()) + { + if (write != read) + { + // copy read to write backwards to close gaps + rColorSteps[write] = rColorSteps[read]; + } + + // always forward write position + write++; + } + } + + // correct size when length is reduced. write is always at + // last used position + 1 + if (rColorSteps.size() > write) + { + rColorSteps.resize(write); + } + + if (bSameColorInit && bAllTheSameColor && rColorSteps.size() > 1) + { + // id all-the-same color is detected, reset to single + // entry, but also force to StartColor and preserve the color + rColorSteps.resize(1); + rColorSteps[0] = ColorStep(0.0, aFirstColor); + } + } + BColor modifyBColor( const ColorSteps& rColorSteps, double fScaler, diff --git a/drawinglayer/qa/unit/vclpixelprocessor2d.cxx b/drawinglayer/qa/unit/vclpixelprocessor2d.cxx index 573c4bdc32f0..343556aec6d1 100644 --- a/drawinglayer/qa/unit/vclpixelprocessor2d.cxx +++ b/drawinglayer/qa/unit/vclpixelprocessor2d.cxx @@ -18,6 +18,7 @@ #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx> #include <drawinglayer/processor2d/baseprocessor2d.hxx> #include <drawinglayer/processor2d/processor2dtools.hxx> +#include <basegfx/utils/gradienttools.hxx> using namespace drawinglayer; @@ -59,8 +60,10 @@ public: basegfx::B2DRange definitionRange(0, 0, 100, 200); basegfx::B2DRange outputRange(0, 100, 100, 200); // Paint only lower half of the gradient. + const basegfx::ColorSteps aColorSteps{ basegfx::ColorStep(0.0, COL_WHITE.getBColor()), + basegfx::ColorStep(1.0, COL_BLACK.getBColor()) }; attribute::FillGradientAttribute attributes(attribute::GradientStyle::Linear, 0, 0, 0, 0, - COL_WHITE.getBColor(), COL_BLACK.getBColor()); + aColorSteps); rtl::Reference<primitive2d::FillGradientPrimitive2D> gradientPrimitive( new primitive2d::FillGradientPrimitive2D(outputRange, definitionRange, attributes)); primitive2d::Primitive2DContainer primitives; diff --git a/drawinglayer/source/attribute/fillgradientattribute.cxx b/drawinglayer/source/attribute/fillgradientattribute.cxx index 07bc82e4e549..3d78273a6428 100644 --- a/drawinglayer/source/attribute/fillgradientattribute.cxx +++ b/drawinglayer/source/attribute/fillgradientattribute.cxx @@ -40,109 +40,31 @@ namespace drawinglayer::attribute double fOffsetX, double fOffsetY, double fAngle, - const basegfx::BColor& rStartColor, - const basegfx::BColor& rEndColor, - const basegfx::ColorSteps* pColorSteps, + const basegfx::ColorSteps& rColorSteps, sal_uInt16 nSteps) : mfBorder(fBorder), mfOffsetX(fOffsetX), mfOffsetY(fOffsetY), mfAngle(fAngle), - maColorSteps(), + maColorSteps(rColorSteps), // copy ColorSteps meStyle(eStyle), mnSteps(nSteps) { - // always add start color to guarantee a color at all. It's also just safer - // to have one and not an empty vector, that spares many checks in the using code - maColorSteps.emplace_back(0.0, rStartColor); - - // if we have given ColorSteps, integrate these - if(nullptr != pColorSteps && !pColorSteps->empty()) - { - // append early to local & sort to prepare the following correction(s) - // and later processing - maColorSteps.insert(maColorSteps.end(), pColorSteps->begin(), pColorSteps->end()); - - // no need to sort knowingly lowest entry StartColor, also guarantees that - // entry to stay at begin - std::sort(maColorSteps.begin() + 1, maColorSteps.end()); - - // use two r/w heads on the data band maColorSteps - size_t curr(0), next(1); - - // during processing, check if all colors are the same. We know the - // StartColor, so to all be the same, all also have to be equal to - // StartColor (including EndColor, use to initialize) - bool bAllTheSameColor(rStartColor == rEndColor); - - // remove entries <= 0.0, >= 1.0 and with equal offset. do - // this inside the already sorted local vector by evtl. - // moving entries closer to begin to keep and adapting size - // at the end - for(; next < maColorSteps.size(); next++) - { - const double fNextOffset(maColorSteps[next].getOffset()); - - // check for < 0.0 (should not really happen, see ::ColorStep) - // also check for == 0.0 which would mean than an implicit - // StartColor was given in ColorSteps - ignore that, we want - // the explicitly given StartColor to always win - if(basegfx::fTools::lessOrEqual(fNextOffset, 0.0)) - continue; - - // check for > 1.0 (should not really happen, see ::ColorStep) - // also check for == 1.0 which would mean than an implicit - // EndColor was given in ColorSteps - ignore that, we want - // the explicitly given EndColor to always win - if(basegfx::fTools::moreOrEqual(fNextOffset, 1.0)) - continue; - - // check for equal current offset - const double fCurrOffset(maColorSteps[curr].getOffset()); - if(basegfx::fTools::equal(fNextOffset, fCurrOffset)) - continue; - - // next is > 0.0, < 1.0 and != curr, so a valid entry. - // take over by evtl. have to move it left - curr++; - if(curr != next) - { - maColorSteps[curr] = maColorSteps[next]; - } - - // new valid entry detected, check it for all the same color - bAllTheSameColor = bAllTheSameColor && maColorSteps[curr].getColor() == rStartColor; - } - - if(bAllTheSameColor) - { - // if all are the same color, reset to StartColor only - maColorSteps.resize(1); - } - else - { - // adapt size to detected useful entries - curr++; - if(curr != maColorSteps.size()) - { - maColorSteps.resize(curr); - } - - // add EndColor if in-between colors were added - // or StartColor != EndColor - if(curr > 1 || rStartColor != rEndColor) - { - maColorSteps.emplace_back(1.0, rEndColor); - } - } - } - else + // Correct the local ColorSteps. That will guarantee that the + // content does contain no offsets < 0.0, > 1.0 or double + // ones, also secures sorted arrangement and checks for + // double colors, too (see there for more information). + // 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::sortAndCorrectColorSteps(maColorSteps); + + // sortAndCorrectColorSteps is rigid and can return + // an empty result. To keep things simple, add a single + // fallback value + if (maColorSteps.empty()) { - // add EndColor if different from StartColor - if(rStartColor != rEndColor) - { - maColorSteps.emplace_back(1.0, rEndColor); - } + maColorSteps.emplace_back(0.0, basegfx::BColor()); } } @@ -204,12 +126,10 @@ namespace drawinglayer::attribute double fOffsetX, double fOffsetY, double fAngle, - const basegfx::BColor& rStartColor, - const basegfx::BColor& rEndColor, - const basegfx::ColorSteps* pColorSteps, + const basegfx::ColorSteps& rColorSteps, sal_uInt16 nSteps) : mpFillGradientAttribute(ImpFillGradientAttribute( - eStyle, fBorder, fOffsetX, fOffsetY, fAngle, rStartColor, rEndColor, pColorSteps, nSteps)) + eStyle, fBorder, fOffsetX, fOffsetY, fAngle, rColorSteps, nSteps)) { } diff --git a/drawinglayer/source/primitive3d/textureprimitive3d.cxx b/drawinglayer/source/primitive3d/textureprimitive3d.cxx index ba998c7f50bb..549932e93049 100644 --- a/drawinglayer/source/primitive3d/textureprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/textureprimitive3d.cxx @@ -20,6 +20,7 @@ #include <primitive3d/textureprimitive3d.hxx> #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> #include <basegfx/color/bcolor.hxx> +#include <basegfx/utils/gradienttools.hxx> #include <utility> @@ -92,7 +93,13 @@ namespace drawinglayer::primitive3d { // create TransparenceTexturePrimitive3D with fixed transparence as replacement const basegfx::BColor aGray(getTransparence(), getTransparence(), getTransparence()); - const attribute::FillGradientAttribute aFillGradient(attribute::GradientStyle::Linear, 0.0, 0.0, 0.0, 0.0, aGray, aGray); + + // create ColorSteps with StartColor == EndCoOlor == aGray + const basegfx::ColorSteps aColorSteps { + basegfx::ColorStep(0.0, aGray), + basegfx::ColorStep(1.0, aGray) }; + + const attribute::FillGradientAttribute aFillGradient(attribute::GradientStyle::Linear, 0.0, 0.0, 0.0, 0.0, aColorSteps); const Primitive3DReference xRef(new TransparenceTexturePrimitive3D(aFillGradient, getChildren(), getTextureSize())); return { xRef }; } diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx index 788594f3b8eb..375e83f9221c 100644 --- a/drawinglayer/source/texture/texture.cxx +++ b/drawinglayer/source/texture/texture.cxx @@ -466,11 +466,9 @@ namespace drawinglayer::texture if (mnColorSteps.size() < 2) return; - // need to start with the offsets *outside* of all loops, these will - // get modified non-linear below, now in more than one gradient section, - // but *constantly* over the whole range - double fAllWidth(0.0); - double fAllHeight(0.0); + // prepare vars dependent on aspect ratio + const double fAR(maGradientInfo.getAspectRatio()); + const bool bMTO(fAR > 1.0); // outer loop over ColorSteps, each is from cs_l to cs_r for (auto cs_l(mnColorSteps.begin()), cs_r(cs_l + 1); cs_r != mnColorSteps.end(); cs_l++, cs_r++) @@ -486,26 +484,21 @@ namespace drawinglayer::texture const double fOffsetEnd(cs_r->getOffset()); const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps); - // prepare individual increments for X/Y dependent on aspect ratio - const double fAR(maGradientInfo.getAspectRatio()); - const bool bMTO(fAR > 1.0); - const double fIncrementX(bMTO ? fStripeWidth / fAR : fStripeWidth); - const double fIncrementY(bMTO ? fStripeWidth : fStripeWidth * fAR); - // get correct start for inner loop (see above) const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0); for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++) { - // next step, actively adapt outer-loop w/h values - fAllWidth += fIncrementX; - fAllHeight += fIncrementY; + // calculate offset position for entry + const double fSize(fOffsetStart + (fStripeWidth * innerLoop)); // set and add at target B2DHomMatrixAndBColor aB2DHomMatrixAndBColor; aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() - * basegfx::utils::createScaleB2DHomMatrix(1.0 - fAllWidth, 1.0 - fAllHeight); + * basegfx::utils::createScaleB2DHomMatrix( + 1.0 - (bMTO ? fSize / fAR : fSize), + 1.0 - (bMTO ? fSize : fSize * fAR)); aB2DHomMatrixAndBColor.maBColor = interpolate(aCStart, aCEnd, double(innerLoop) / double(nSteps - 1)); rEntries.push_back(aB2DHomMatrixAndBColor); } @@ -656,11 +649,9 @@ namespace drawinglayer::texture if (mnColorSteps.size() < 2) return; - // need to start with the offsets *outside* of all loops, these will - // get modified non-linear below, now in more than one gradient section, - // but *constantly* over the whole range - double fAllWidth(0.0); - double fAllHeight(0.0); + // prepare vars dependent on aspect ratio + const double fAR(maGradientInfo.getAspectRatio()); + const bool bMTO(fAR > 1.0); // outer loop over ColorSteps, each is from cs_l to cs_r for (auto cs_l(mnColorSteps.begin()), cs_r(cs_l + 1); cs_r != mnColorSteps.end(); cs_l++, cs_r++) @@ -676,26 +667,21 @@ namespace drawinglayer::texture const double fOffsetEnd(cs_r->getOffset()); const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps); - // prepare individual increments for X/Y dependent on aspect ratio - const double fAR(maGradientInfo.getAspectRatio()); - const bool bMTO(fAR > 1.0); - const double fIncrementX(bMTO ? fStripeWidth / fAR : fStripeWidth); - const double fIncrementY(bMTO ? fStripeWidth : fStripeWidth * fAR); - // get correct start for inner loop (see above) const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0); for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++) { - // next step, actively adapt outer-loop w/h values - fAllWidth += fIncrementX; - fAllHeight += fIncrementY; + // calculate offset position for entry + const double fSize(fOffsetStart + (fStripeWidth * innerLoop)); // set and add at target B2DHomMatrixAndBColor aB2DHomMatrixAndBColor; aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() - * basegfx::utils::createScaleB2DHomMatrix(1.0 - fAllWidth, 1.0 - fAllHeight); + * basegfx::utils::createScaleB2DHomMatrix( + 1.0 - (bMTO ? fSize / fAR : fSize), + 1.0 - (bMTO ? fSize : fSize * fAR)); aB2DHomMatrixAndBColor.maBColor = interpolate(aCStart, aCEnd, double(innerLoop) / double(nSteps - 1)); rEntries.push_back(aB2DHomMatrixAndBColor); } diff --git a/drawinglayer/source/tools/wmfemfhelper.cxx b/drawinglayer/source/tools/wmfemfhelper.cxx index 0189c621fda3..27e6a6c94e24 100644 --- a/drawinglayer/source/tools/wmfemfhelper.cxx +++ b/drawinglayer/source/tools/wmfemfhelper.cxx @@ -711,15 +711,17 @@ namespace wmfemfhelper } } + const basegfx::ColorSteps aColorSteps { + basegfx::ColorStep(0.0, aStart), + basegfx::ColorStep(1.0, aEnd) }; + return drawinglayer::attribute::FillGradientAttribute( aGradientStyle, static_cast<double>(rGradient.GetBorder()) * 0.01, static_cast<double>(rGradient.GetOfsX()) * 0.01, static_cast<double>(rGradient.GetOfsY()) * 0.01, toRadians(rGradient.GetAngle()), - aStart, - aEnd, - nullptr, + aColorSteps, rGradient.GetSteps()); } diff --git a/include/basegfx/utils/gradienttools.hxx b/include/basegfx/utils/gradienttools.hxx index 793d07a75577..328a86b8335c 100644 --- a/include/basegfx/utils/gradienttools.hxx +++ b/include/basegfx/utils/gradienttools.hxx @@ -69,9 +69,18 @@ namespace basegfx // e.g. for usage in std::vector::insert // ensure [0.0 .. 1.0] range for mfOffset ColorStep(double fOffset = 0.0, const BColor& rColor = BColor()) - : mfOffset(std::max(0.0, std::min(fOffset, 1.0))) + : mfOffset(fOffset) , maColor(rColor) { + // NOTE: I originally *corrected* mfOffset here by using + // mfOffset(std::max(0.0, std::min(fOffset, 1.0))) + // While that is formally correct, it moves an invalid + // entry to 0.0 or 1.0, thus creating additional wrong + // Start/EndColor entries. That may then 'overlay' the + // cortrect entry when corrections are applied to the + // vector of entries (see sortAndCorrectColorSteps) + // which leads to getting the wanted Start/EndColor + // to be factically deleted, what is an error. } double getOffset() const { return mfOffset; } @@ -184,6 +193,26 @@ namespace basegfx namespace utils { + /* Helper to sort and correct ColorSteps. This will + sort and then correct the given ColorSteps. The + corrected version will + - be sorted + - have no double values + - have no values with offset < 0.0 + - have no values with offset > 1.0 + thus be ready to be used in multi-color gradients. + + NOTE: The returned version may be empty (!) if no + valid entries were contained + NOTE: It does not necessarily contain values for + offset == 0.0 and 1.0 if there were none + given (so no Start/EndColor) + NOTE: If it contains only one entry that entry is + set to StartColor and the Color is preserved. + This is also done when all Colors are the same + */ + BASEGFX_DLLPUBLIC void sortAndCorrectColorSteps(ColorSteps& rColorSteps); + /* Helper to grep the correct ColorStep out of ColorSteps and interpolate as needed for given relative value in fScaler in the range of [0.0 .. 1.0]. diff --git a/include/drawinglayer/attribute/fillgradientattribute.hxx b/include/drawinglayer/attribute/fillgradientattribute.hxx index 4b736e678181..3a62ee41e43c 100644 --- a/include/drawinglayer/attribute/fillgradientattribute.hxx +++ b/include/drawinglayer/attribute/fillgradientattribute.hxx @@ -55,15 +55,15 @@ private: public: /* MCGR: Adaptions for MultiColorGradients - To force providing start/end colors these are still part of the - constructor (see rStartColor/rEndColor). To also provide - GradientSteps these need to be handed over by ColorSteps data - if wanted/needed. + Direct Start/EndCOlor is no longer required, instead the + full color gradient is handed over as ColorSteps vector. + To add the former Start/EndColor in a compatible way, just + prepare an instance of basegfx::ColorSteps with the + StartColor at 0.0 and the EndColor at 1.0. - Start/EndColor will be added to the internal ColorSteps with - the according default offsets. A rigid correction/input data - testing is done by the constructor, including to sort the - ColorSteps by offset. + A rigid correction/input data will be done by the constructor, + including to sort the ColorSteps by offset and removing invalid + entries (see sortAndCorrectColorSteps) To access e.g. the StartColor, use getColorSteps().front(), and getColorSteps().back(), accordingly, for EndColor. The existence @@ -74,9 +74,8 @@ public: */ /// constructors/assignmentoperator/destructor FillGradientAttribute(GradientStyle eStyle, double fBorder, double fOffsetX, double fOffsetY, - double fAngle, const basegfx::BColor& rStartColor, - const basegfx::BColor& rEndColor, - const basegfx::ColorSteps* pColorSteps = nullptr, sal_uInt16 nSteps = 0); + double fAngle, const basegfx::ColorSteps& rColorSteps, + sal_uInt16 nSteps = 0); FillGradientAttribute(); FillGradientAttribute(const FillGradientAttribute&); FillGradientAttribute(FillGradientAttribute&&); diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx index 048d5430f6f8..0e0369b08a43 100644 --- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx +++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx @@ -493,7 +493,13 @@ namespace drawinglayer::primitive2d aEnd = interpolate(aBlack, aEnd, static_cast<double>(nEndIntens) * 0.01); } - basegfx::ColorSteps aColorSteps; + // prepare ColorSteps + // currently always two (Start/EndColor) to stay compatible + // for now, but that will change. It already gets manipulated + // by the test cases below + basegfx::ColorSteps aColorSteps { + basegfx::ColorStep(0.0, aStart), + basegfx::ColorStep(1.0, aEnd) }; // test code here, can/will be removed later static sal_uInt32 nUseGradientSteps(0); @@ -502,11 +508,12 @@ namespace drawinglayer::primitive2d case 1: { // just test a nice valid gradient - aStart = basegfx::BColor(1.0, 0.0, 0.0); // red - aEnd = basegfx::BColor(0.0, 0.0, 1.0); // blue + aColorSteps.clear(); + aColorSteps.emplace_back(0.0, basegfx::BColor(1.0, 0.0, 0.0)); // red aColorSteps.emplace_back(0.25, basegfx::BColor(0.0, 1.0, 0.0)); // green@25% aColorSteps.emplace_back(0.50, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50% aColorSteps.emplace_back(0.75, basegfx::BColor(1.0, 0.0, 1.0)); // pink@75% + aColorSteps.emplace_back(1.0, basegfx::BColor(0.0, 0.0, 1.0)); // blue break; } @@ -527,6 +534,7 @@ namespace drawinglayer::primitive2d case 4: { // check additional EndColor, the one given directly has to win + // due this one being added *after* the original one aColorSteps.emplace_back(1.0, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50% break; } @@ -547,7 +555,7 @@ namespace drawinglayer::primitive2d case 7: { - // check in-between single-color part + // check in-between single-color section aColorSteps.emplace_back(0.3, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50% aColorSteps.emplace_back(0.7, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50% break; @@ -555,10 +563,11 @@ namespace drawinglayer::primitive2d case 8: { - // check in-between single-color parts + // check in-between single-color sections aColorSteps.emplace_back(0.2, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50% - aColorSteps.emplace_back(0.4, aEnd); - aColorSteps.emplace_back(0.6, aStart); + aColorSteps.emplace_back(0.4, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50% + aColorSteps.emplace_back(0.5, aStart); + aColorSteps.emplace_back(0.6, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50% aColorSteps.emplace_back(0.8, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50% break; } @@ -573,7 +582,16 @@ namespace drawinglayer::primitive2d case 10: { // check single-color end area - aColorSteps.emplace_back(0.6, aEnd); + aColorSteps.emplace_back(0.4, aEnd); + break; + } + + case 11: + { + // check case without direct Start/EndColor + aColorSteps.clear(); + aColorSteps.emplace_back(0.4, aEnd); + aColorSteps.emplace_back(0.6, aStart); break; } @@ -589,9 +607,7 @@ namespace drawinglayer::primitive2d static_cast<double>(aXGradient.GetXOffset()) * 0.01, static_cast<double>(aXGradient.GetYOffset()) * 0.01, toRadians(aXGradient.GetAngle()), - aStart, - aEnd, - aColorSteps.empty() ? nullptr : &aColorSteps, + aColorSteps, rSet.Get(XATTR_GRADIENTSTEPCOUNT).GetValue()); break; @@ -745,14 +761,17 @@ namespace drawinglayer::primitive2d const double fStartLum(nStartLuminance / 255.0); const double fEndLum(nEndLuminance / 255.0); + const basegfx::ColorSteps aColorSteps { + basegfx::ColorStep(0.0, basegfx::BColor(fStartLum, fStartLum, fStartLum)), + basegfx::ColorStep(1.0, basegfx::BColor(fEndLum, fEndLum, fEndLum)) }; + return attribute::FillGradientAttribute( XGradientStyleToGradientStyle(rGradient.GetGradientStyle()), static_cast<double>(rGradient.GetBorder()) * 0.01, static_cast<double>(rGradient.GetXOffset()) * 0.01, static_cast<double>(rGradient.GetYOffset()) * 0.01, toRadians(rGradient.GetAngle()), - basegfx::BColor(fStartLum, fStartLum, fStartLum), - basegfx::BColor(fEndLum, fEndLum, fEndLum)); + aColorSteps); } } diff --git a/svx/source/xoutdev/xtabgrdt.cxx b/svx/source/xoutdev/xtabgrdt.cxx index bc8f79ac0426..219ee2801d69 100644 --- a/svx/source/xoutdev/xtabgrdt.cxx +++ b/svx/source/xoutdev/xtabgrdt.cxx @@ -35,6 +35,7 @@ #include <drawinglayer/processor2d/baseprocessor2d.hxx> #include <drawinglayer/processor2d/processor2dtools.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/utils/gradienttools.hxx> #include <memory> using namespace com::sun::star; @@ -152,14 +153,17 @@ BitmapEx XGradientList::CreateBitmap( tools::Long nIndex, const Size& rSize ) co } } + const basegfx::ColorSteps aColorSteps { + basegfx::ColorStep(0.0, aStart), + basegfx::ColorStep(1.0, aEnd) }; + drawinglayer::attribute::FillGradientAttribute aFillGradient( aGradientStyle, static_cast<double>(rGradient.GetBorder()) * 0.01, static_cast<double>(rGradient.GetXOffset()) * 0.01, static_cast<double>(rGradient.GetYOffset()) * 0.01, toRadians(rGradient.GetAngle()), - aStart, - aEnd); + aColorSteps); const drawinglayer::primitive2d::Primitive2DReference aGradientPrimitive( new drawinglayer::primitive2d::PolyPolygonGradientPrimitive2D( diff --git a/sw/source/uibase/docvw/HeaderFooterWin.cxx b/sw/source/uibase/docvw/HeaderFooterWin.cxx index 763d6d729e12..186deaa12ab2 100644 --- a/sw/source/uibase/docvw/HeaderFooterWin.cxx +++ b/sw/source/uibase/docvw/HeaderFooterWin.cxx @@ -29,6 +29,7 @@ #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/range/b2drectangle.hxx> #include <basegfx/vector/b2dsize.hxx> +#include <basegfx/utils/gradienttools.hxx> #include <drawinglayer/attribute/fillgradientattribute.hxx> #include <drawinglayer/attribute/fontattribute.hxx> #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx> @@ -150,7 +151,11 @@ void SwFrameButtonPainter::PaintButton(drawinglayer::primitive2d::Primitive2DCon double nAngle = M_PI; if (bOnTop) nAngle = 0; - FillGradientAttribute aFillAttrs(drawinglayer::attribute::GradientStyle::Linear, 0.0, 0.0, 0.0, nAngle, aLighterColor, aFillColor); + + const basegfx::ColorSteps aColorSteps { + basegfx::ColorStep(0.0, aLighterColor), + basegfx::ColorStep(1.0, aFillColor) }; + FillGradientAttribute aFillAttrs(drawinglayer::attribute::GradientStyle::Linear, 0.0, 0.0, 0.0, nAngle, aColorSteps ); rSeq.push_back(drawinglayer::primitive2d::Primitive2DReference( new drawinglayer::primitive2d::FillGradientPrimitive2D(aGradientRect, std::move(aFillAttrs)))); } diff --git a/sw/source/uibase/docvw/ShadowOverlayObject.cxx b/sw/source/uibase/docvw/ShadowOverlayObject.cxx index 3b7490678533..002a40d5db91 100644 --- a/sw/source/uibase/docvw/ShadowOverlayObject.cxx +++ b/sw/source/uibase/docvw/ShadowOverlayObject.cxx @@ -27,6 +27,7 @@ #include <sw_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/primitivetools2d.hxx> #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx> +#include <basegfx/utils/gradienttools.hxx> namespace sw::sidebarwindows { @@ -82,14 +83,17 @@ void ShadowPrimitive::create2DDecomposition( case SS_NORMAL: { aRange.expand(basegfx::B2DTuple(getSecondPosition().getX(), getSecondPosition().getY() + (2.0 * getDiscreteUnit()))); + + const basegfx::ColorSteps aColorSteps { + basegfx::ColorStep(0.0, basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0)), + basegfx::ColorStep(1.0, basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0)) }; ::drawinglayer::attribute::FillGradientAttribute aFillGradientAttribute( drawinglayer::attribute::GradientStyle::Linear, 0.0, 0.5, 0.5, M_PI, - basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0), - basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0)); + aColorSteps); rContainer.push_back( new drawinglayer::primitive2d::FillGradientPrimitive2D( @@ -100,14 +104,16 @@ void ShadowPrimitive::create2DDecomposition( case SS_VIEW: { aRange.expand(basegfx::B2DTuple(getSecondPosition().getX(), getSecondPosition().getY() + (4.0 * getDiscreteUnit()))); + const basegfx::ColorSteps aColorSteps { + basegfx::ColorStep(0.0, basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0)), + basegfx::ColorStep(1.0, basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0)) }; drawinglayer::attribute::FillGradientAttribute aFillGradientAttribute( drawinglayer::attribute::GradientStyle::Linear, 0.0, 0.5, 0.5, M_PI, - basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0), - basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0)); + aColorSteps); rContainer.push_back( new drawinglayer::primitive2d::FillGradientPrimitive2D( @@ -118,14 +124,16 @@ void ShadowPrimitive::create2DDecomposition( case SS_EDIT: { aRange.expand(basegfx::B2DTuple(getSecondPosition().getX(), getSecondPosition().getY() + (4.0 * getDiscreteUnit()))); + const basegfx::ColorSteps aColorSteps { + basegfx::ColorStep(0.0, basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0)), + basegfx::ColorStep(1.0, basegfx::BColor(83.0/255.0,83.0/255.0,83.0/255.0)) }; drawinglayer::attribute::FillGradientAttribute aFillGradientAttribute( drawinglayer::attribute::GradientStyle::Linear, 0.0, 0.5, 0.5, M_PI, - basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0), - basegfx::BColor(83.0/255.0,83.0/255.0,83.0/255.0)); + aColorSteps); rContainer.push_back( new drawinglayer::primitive2d::FillGradientPrimitive2D( |