summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorArmin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de>2023-03-13 19:39:34 +0100
committerAndras Timar <andras.timar@collabora.com>2023-05-15 21:38:53 +0200
commit6f700c779cb084c605c9f0c56b4c66a17aef1d8d (patch)
treeaf382d0ad009ba8d628e2191dc1d2b1245322aa8 /include
parent2f2e108b37589c47bf666d84322cf4e9e700c204 (diff)
MCGR: Model data changes for ColorSteps
Added tooling replaceStart/EndColor to allow simple transition for code that does not immediately adapt to multi color gradients. Also added createColorStepsFromStartEndColor for the same purpose. Adapted XGradient to no longer have Start/EndColor at all, but only use ColorSteps. Adapted all usages of XGradient to no longer use Get/Set/Start/EndColor, but access the ColorSteps instead. Replaced quite some XGradient constructors that used XGradient() as Start/EndColor since this is already the default. Adapted ColorBlending to black AKA Start/EndIntens in XGradient to work now on all ColorSteps in the required linearly-scaled manner. UNO API changes: Added com::sun::star::awt::ColorStep as basic data element that holds a pair of Offset and Color. Added com::sun::star::awt::ColorStepSequence to handle an array of sorted entries. Added com::sun::star::awt::Gradient2 derived from com::sun::star::awt::Gradient, extended by the needed com::sun::star::awt::ColorStepSequence. Added MID_GRADIENT_COLORSTEPSEQUENCE to UNO API to provide access to ColorSteps directly. Adapted XFillGradientItem::QueryValue/PutValue to make use of new UNO API data structures. To do so, added tooling methods for data transition: - fillColorStepSequenceFromColorSteps - fillGradient2FromXGradient - fillColorStepsFromAny - fillXGradientFromAny and adapted - case '0' (all data) - MID_FILLGRADIENT - MID_GRADIENT_COLORSTEPSEQUENCE - MID_GRADIENT_START/ENDCOLOR to make use of these. Tested usage of these in the office. Renamed from GradientStep to GradientStop after discussions with members on the list to make this closer related to other norms/definitions. Also renamed classes and class members to better reflect to GradientStop, so grepping/finding will be easier (e.g. 'Color' just exists pretty often, but 'StopColor' is more precise). Changed the used UNO API class for reprsenting the Color to better reflect to ranges [0.0 .. 1.0] and usage of RGB. Change-Id: I1eeb3e97e81d6785967615d1ff256551fc3b882d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148849 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'include')
-rw-r--r--include/basegfx/utils/gradienttools.hxx138
-rw-r--r--include/drawinglayer/attribute/fillgradientattribute.hxx20
-rw-r--r--include/svx/unomid.hxx1
-rw-r--r--include/svx/xgrad.hxx21
4 files changed, 114 insertions, 66 deletions
diff --git a/include/basegfx/utils/gradienttools.hxx b/include/basegfx/utils/gradienttools.hxx
index 328a86b8335c..85802749478c 100644
--- a/include/basegfx/utils/gradienttools.hxx
+++ b/include/basegfx/utils/gradienttools.hxx
@@ -27,12 +27,14 @@
#include <utility>
#include <basegfx/basegfxdllapi.h>
#include <vector>
+#include <com/sun/star/awt/ColorStopSequence.hdl>
+namespace com { namespace sun { namespace star { namespace uno { class Any; } } } }
namespace basegfx { class B2DRange; }
namespace basegfx
{
- /* MCGR: Provide ColorStep definition
+ /* MCGR: Provide ColorStop definition
This is the needed combination of offset and color:
@@ -52,59 +54,60 @@ namespace basegfx
Color is defined as:
- RGB with unit values [0.0 .. 1.0]
- These definitions are packed in a std::vector<ColorStep> ColorSteps,
+ These definitions are packed in a std::vector<ColorStop> ColorStops,
see typedef below.
*/
- class UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) ColorStep
+ class UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) ColorStop
{
private:
- // offset in the range of [0.0 .. 1.0], checked & force by constructor
- double mfOffset;
+ // offset in the range of [0.0 .. 1.0]
+ double mfStopOffset;
- // color of ColorStep entry
- BColor maColor;
+ // RGB color of ColorStop entry
+ BColor maStopColor;
public:
// constructor - defaults are needed to have a default constructor
- // 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(fOffset)
- , maColor(rColor)
+ // e.g. for usage in std::vector::insert (even when only reducing)
+ // ensure [0.0 .. 1.0] range for mfStopOffset
+ ColorStop(double fStopOffset = 0.0, const BColor& rStopColor = BColor())
+ : mfStopOffset(fStopOffset)
+ , maStopColor(rStopColor)
{
- // NOTE: I originally *corrected* mfOffset here by using
- // mfOffset(std::max(0.0, std::min(fOffset, 1.0)))
+ // NOTE: I originally *corrected* mfStopOffset here by using
+ // mfStopOffset(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)
+ // correct entry when corrections are applied to the
+ // vector of entries (see sortAndCorrectColorStops)
// which leads to getting the wanted Start/EndColor
// to be factically deleted, what is an error.
}
- double getOffset() const { return mfOffset; }
- const BColor& getColor() const { return maColor; }
+ double getStopOffset() const { return mfStopOffset; }
+ const BColor& getStopColor() const { return maStopColor; }
- bool operator<(const ColorStep& rCandidate) const
+ // needed for std::sort
+ bool operator<(const ColorStop& rCandidate) const
{
- return getOffset() < rCandidate.getOffset();
+ return getStopOffset() < rCandidate.getStopOffset();
}
- bool operator==(const ColorStep& rCandidate) const
+ bool operator==(const ColorStop& rCandidate) const
{
- return getOffset() == rCandidate.getOffset() && getColor() == rCandidate.getColor();
+ return getStopOffset() == rCandidate.getStopOffset() && getStopColor() == rCandidate.getStopColor();
}
};
- /* MCGR: Provide ColorSteps definition to the FillGradientAttribute
+ /* MCGR: Provide ColorStops definition to the FillGradientAttribute
This array should be sorted ascending by offsets, from lowest to
highest. Since all the primitive data definition where it is used
is read-only, this can/will be guaranteed by forcing/checking this
in the constructor, see ::FillGradientAttribute
*/
- typedef std::vector<ColorStep> ColorSteps;
+ typedef std::vector<ColorStop> ColorStops;
/** Gradient definition as used in ODF 1.2
@@ -193,33 +196,78 @@ 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
+ /* Tooling method to convert UNO API data to ColorStops.
+ This will try to extract ColorStop data from the given
+ Any, so if it's of type awt::Gradient2 that data will be
+ extracted, converted and copied into the given ColorStops.
*/
- BASEGFX_DLLPUBLIC void sortAndCorrectColorSteps(ColorSteps& rColorSteps);
+ BASEGFX_DLLPUBLIC void fillColorStopsFromAny(ColorStops& rColorStops, const css::uno::Any& rVal);
- /* Helper to grep the correct ColorStep out of
- ColorSteps and interpolate as needed for given
+ /* Tooling method to fill a awt::ColorStopSequence with
+ the data from the given ColorStops. This is used in
+ UNO API implementations.
+ */
+ BASEGFX_DLLPUBLIC void fillColorStopSequenceFromColorStops(css::awt::ColorStopSequence& rColorStopSequence, const ColorStops& rColorStops);
+
+ /* Tooling method that allows to replace the StartColor in a
+ vector of ColorStops. A vector in 'ordered state' is expected,
+ so you may use/have used sortAndCorrectColorStops, see below.
+ This method is for convenience & backwards compatibility, please
+ think about handling multi-colored gradients directly.
+ */
+ BASEGFX_DLLPUBLIC void replaceStartColor(ColorStops& rColorStops, const BColor& rStart);
+
+ /* Tooling method that allows to replace the EndColor in a
+ vector of ColorStops. A vector in 'ordered state' is expected,
+ so you may use/have used sortAndCorrectColorStops, see below.
+ This method is for convenience & backwards compatibility, please
+ think about handling multi-colored gradients directly.
+ */
+ BASEGFX_DLLPUBLIC void replaceEndColor(ColorStops& rColorStops, const BColor& rEnd);
+
+ // Tooling method to quickly create a ColorStop vector for a given set of Start/EndColor
+ BASEGFX_DLLPUBLIC ColorStops createColorStopsFromStartEndColor(const BColor& rStart, const BColor& rEnd);
+
+ /* Tooling method to guarantee sort and correctness for
+ the given ColorStops vector.
+ A vector fulfilling these conditions is called to be
+ in 'ordered state'.
+
+ At return, the following conditions are guaranteed:
+ - contains no ColorStops with offset < 0.0 (will
+ be removed)
+ - contains no ColorStops with offset > 1.0 (will
+ be removed)
+ - contains no two ColorStops with identical offsets
+ (will be removed, 1st one/smallest offset wins
+ which is also given by sort tooling)
+ - will be sorted from lowest offset to highest
+ - if all colors are the same, the content will
+ be reduced to a single entry with offset 0.0
+ (force to 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 technically required
+ - A entry with 1.0 is not required or forced, so
+ no 'EndColor' is technically required
+
+ All this is done in one run (sort + O(N)) without
+ creating a copy of the data in any form
+ */
+ BASEGFX_DLLPUBLIC void sortAndCorrectColorStops(ColorStops& rColorStops);
+
+ /* Helper to grep the correct ColorStop out of
+ ColorStops and interpolate as needed for given
relative value in fScaler in the range of [0.0 .. 1.0].
It also takes care of evtl. given RequestedSteps.
*/
BASEGFX_DLLPUBLIC BColor modifyBColor(
- const ColorSteps& rColorSteps,
+ const ColorStops& rColorStops,
double fScaler,
sal_uInt32 nRequestedSteps);
diff --git a/include/drawinglayer/attribute/fillgradientattribute.hxx b/include/drawinglayer/attribute/fillgradientattribute.hxx
index 50d169cb5772..8a2df4d6baaf 100644
--- a/include/drawinglayer/attribute/fillgradientattribute.hxx
+++ b/include/drawinglayer/attribute/fillgradientattribute.hxx
@@ -25,9 +25,9 @@
namespace basegfx
{
-class ColorStep;
+class ColorStop;
class BColor;
-typedef std::vector<ColorStep> ColorSteps;
+typedef std::vector<ColorStop> ColorStops;
}
namespace drawinglayer::attribute
@@ -56,17 +56,17 @@ public:
/* MCGR: Adaptions for MultiColorGradients
Direct Start/EndCOlor is no longer required, instead the
- full color gradient is handed over as ColorSteps vector.
+ full color gradient is handed over as ColorStops vector.
To add the former Start/EndColor in a compatible way, just
- prepare an instance of basegfx::ColorSteps with the
+ prepare an instance of basegfx::ColorStops with the
StartColor at 0.0 and the EndColor at 1.0.
A rigid correction/input data will be done by the constructor,
- including to sort the ColorSteps by offset and removing invalid
- entries (see sortAndCorrectColorSteps)
+ including to sort the ColorStops by offset and removing invalid
+ entries (see sortAndCorrectColorStops)
- To access e.g. the StartColor, use getColorSteps().front(), and
- getColorSteps().back(), accordingly, for EndColor. The existance
+ To access e.g. the StartColor, use getColorStops().front(), and
+ getColorStops().back(), accordingly, for EndColor. The existence
of at least one entry is guaranteed, so no need to check before
accessing using of front()/back() calls. If only one color entry
exists, start == end color is assumed, so not really a gradient
@@ -74,7 +74,7 @@ public:
*/
/// constructors/assignmentoperator/destructor
FillGradientAttribute(GradientStyle eStyle, double fBorder, double fOffsetX, double fOffsetY,
- double fAngle, const basegfx::ColorSteps& rColorSteps,
+ double fAngle, const basegfx::ColorStops& rColorStops,
sal_uInt16 nSteps = 0);
FillGradientAttribute();
FillGradientAttribute(const FillGradientAttribute&);
@@ -98,7 +98,7 @@ public:
double getOffsetX() const;
double getOffsetY() const;
double getAngle() const;
- const basegfx::ColorSteps& getColorSteps() const;
+ const basegfx::ColorStops& getColorStops() const;
sal_uInt16 getSteps() const;
};
diff --git a/include/svx/unomid.hxx b/include/svx/unomid.hxx
index fe07fee51054..766996a57ac0 100644
--- a/include/svx/unomid.hxx
+++ b/include/svx/unomid.hxx
@@ -71,6 +71,7 @@
#define MID_GRADIENT_STARTINTENSITY 9
#define MID_GRADIENT_ENDINTENSITY 10
#define MID_GRADIENT_STEPCOUNT 11
+#define MID_GRADIENT_COLORSTOPSEQUENCE 12
// XFillHatchItem
// Don't use 0 as it used for the whole struct
diff --git a/include/svx/xgrad.hxx b/include/svx/xgrad.hxx
index 553dfe23b93b..9dda79d06c7c 100644
--- a/include/svx/xgrad.hxx
+++ b/include/svx/xgrad.hxx
@@ -25,15 +25,16 @@
#include <svx/svxdllapi.h>
#include <com/sun/star/awt/GradientStyle.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
-#include <com/sun/star/awt/Gradient.hpp>
-
-class Gradient;
+#include <com/sun/star/awt/Gradient2.hpp>
+#include <basegfx/utils/gradienttools.hxx>
class SAL_WARN_UNUSED SVXCORE_DLLPUBLIC XGradient final
{
css::awt::GradientStyle eStyle;
- Color aStartColor;
- Color aEndColor;
+
+ // MCGS: ColorStops in the range [0.0 .. 1.0], including StartColor/EndColor
+ basegfx::ColorStops aColorStops;
+
Degree10 nAngle;
sal_uInt16 nBorder;
sal_uInt16 nOfsX;
@@ -46,7 +47,7 @@ class SAL_WARN_UNUSED SVXCORE_DLLPUBLIC XGradient final
public:
XGradient();
- XGradient( const Color& rStart, const Color& rEnd,
+ XGradient( const basegfx::ColorStops& rColorStops,
css::awt::GradientStyle eStyle = css::awt::GradientStyle_LINEAR, Degree10 nAngle = 0_deg10,
sal_uInt16 nXOfs = 50, sal_uInt16 nYOfs = 50, sal_uInt16 nBorder = 0,
sal_uInt16 nStartIntens = 100, sal_uInt16 nEndIntens = 100,
@@ -55,8 +56,7 @@ public:
bool operator==(const XGradient& rGradient) const;
void SetGradientStyle(css::awt::GradientStyle eNewStyle) { eStyle = eNewStyle; }
- void SetStartColor(const Color& rColor) { aStartColor = rColor; }
- void SetEndColor(const Color& rColor) { aEndColor = rColor; }
+ void SetColorStops(const basegfx::ColorStops& rSteps);
void SetAngle(Degree10 nNewAngle) { nAngle = nNewAngle; }
void SetBorder(sal_uInt16 nNewBorder) { nBorder = nNewBorder; }
void SetXOffset(sal_uInt16 nNewOffset) { nOfsX = nNewOffset; }
@@ -66,8 +66,7 @@ public:
void SetSteps(sal_uInt16 nSteps) { nStepCount = nSteps; }
css::awt::GradientStyle GetGradientStyle() const { return eStyle; }
- const Color& GetStartColor() const { return aStartColor; }
- const Color& GetEndColor() const { return aEndColor; }
+ const basegfx::ColorStops& GetColorStops() const { return aColorStops; }
Degree10 GetAngle() const { return nAngle; }
sal_uInt16 GetBorder() const { return nBorder; }
sal_uInt16 GetXOffset() const { return nOfsX; }
@@ -78,7 +77,7 @@ public:
boost::property_tree::ptree dumpAsJSON() const;
static XGradient fromJSON(std::u16string_view rJSON);
- css::awt::Gradient toGradientUNO() const;
+ css::awt::Gradient2 toGradientUNO() const;
};
#endif