include/docmodel/color/ComplexColor.hxx                    |   37 ++
 include/docmodel/styles/ChartStyle.hxx                     |    1 
 include/oox/drawingml/clrscheme.hxx                        |    2 
 include/oox/drawingml/color.hxx                            |   47 --
 oox/inc/drawingml/colorchoicecontext.hxx                   |   14 
 oox/inc/drawingml/misccontexts.hxx                         |   36 +-
 oox/inc/drawingml/textcharacterproperties.hxx              |    5 
 oox/source/drawingml/chart/stylefragment.cxx               |    4 
 oox/source/drawingml/clrschemecontext.cxx                  |    2 
 oox/source/drawingml/color.cxx                             |  234 +++++++------
 oox/source/drawingml/colorchoicecontext.cxx                |  105 ++---
 oox/source/drawingml/diagram/diagramfragmenthandler.cxx    |    2 
 oox/source/drawingml/effectpropertiescontext.cxx           |   10 
 oox/source/drawingml/misccontexts.cxx                      |   26 -
 oox/source/drawingml/scene3dcontext.cxx                    |    8 
 oox/source/drawingml/shapestylecontext.cxx                 |    2 
 oox/source/drawingml/table/tablebackgroundstylecontext.cxx |    2 
 oox/source/drawingml/table/tablecontext.cxx                |    2 
 oox/source/drawingml/table/tablestylecellstylecontext.cxx  |    4 
 oox/source/drawingml/table/tablestyletextstylecontext.cxx  |    4 
 oox/source/drawingml/textcharacterproperties.cxx           |   13 
 oox/source/drawingml/textcharacterpropertiescontext.cxx    |   14 
 oox/source/drawingml/textparagraphpropertiescontext.cxx    |    2 
 oox/source/export/ThemeExport.cxx                          |    3 
 oox/source/ppt/animvariantcontext.cxx                      |    2 
 oox/source/ppt/slidefragmenthandler.cxx                    |    2 
 oox/source/ppt/timenodelistcontext.cxx                     |    4 
 27 files changed, 321 insertions(+), 266 deletions(-)

New commits:
commit a07bad0cc8d4ec8490a9afd05299dac635d2ec90
Author:     Kurt Nordback <[email protected]>
AuthorDate: Wed Nov 26 23:48:09 2025 +0900
Commit:     Tomaž Vajngerl <[email protected]>
CommitDate: Thu Nov 27 01:33:12 2025 +0100

    oox: next step to replace oox::drawingml::Color with ComplexColor
    
    ComplexColor is a replacement for oox::drawingml::Color, so both
    share a lot in common, but oox::drawingml::Color is only used to
    resolve the colors inside oox. The idea is to replace step by step
    oox::drawingml::Color with ComplexColor. In this step a lot of
    ComplexColor types are used instead in oox::drawingml::Color types.
    
    Additionally oox::drawingml::Color is not mandatory anymore for
    a lot of contexts, so depending on the need ComplexColor can be
    used or oox::drawingml::Color.
    
    Change-Id: I6613a0f63cc9b7d070841d4f667363b03e6cbaa8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194645
    Code-Style: Tomaž Vajngerl <[email protected]>
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    Tested-by: Jenkins

diff --git a/include/docmodel/color/ComplexColor.hxx 
b/include/docmodel/color/ComplexColor.hxx
index bd149b67a518..e57530936bda 100644
--- a/include/docmodel/color/ComplexColor.hxx
+++ b/include/docmodel/color/ComplexColor.hxx
@@ -30,6 +30,7 @@ enum class ColorType
     Palette, /// Color from application defined palette.
     System, /// Color from system palette.
     Placeholder, /// Placeholder color in theme style lists.
+    Finalized /// Finalized RGB color.
 };
 
 enum class SystemColorType
@@ -106,6 +107,18 @@ public:
         return meType == model::ColorType::Theme && meThemeColorType != 
ThemeColorType::Unknown;
     }
 
+    bool isUsed() const
+    {
+        return !(meType == ColorType::Unused
+                 || (meType == ColorType::System && meSystemColorType == 
SystemColorType::Unused));
+    }
+
+    void assignIfUsed(const ComplexColor& rColor)
+    {
+        if (rColor.isUsed())
+            *this = rColor;
+    }
+
     ThemeColorUsage getThemeColorUsage() const { return meThemeColorUsage; }
     void setThemeColorUsage(ThemeColorUsage eThemeColorUsage)
     {
@@ -187,6 +200,30 @@ public:
         meType = ColorType::System;
     }
 
+    bool isOpaque() const
+    {
+        for (const Transformation& t : maTransformations)
+        {
+            if (t.meType == model::TransformationType::Alpha && t.mnValue != 
10000)
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    bool isTransparent() const
+    {
+        for (const Transformation& t : maTransformations)
+        {
+            if (t.meType == model::TransformationType::Alpha && t.mnValue == 0)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
     void setThemePlaceholder() { meType = ColorType::Placeholder; }
 
     void setThemeColor(ThemeColorType eType)
diff --git a/include/docmodel/styles/ChartStyle.hxx 
b/include/docmodel/styles/ChartStyle.hxx
index 2ab6a6cf5414..041dfe92ec13 100644
--- a/include/docmodel/styles/ChartStyle.hxx
+++ b/include/docmodel/styles/ChartStyle.hxx
@@ -91,7 +91,6 @@ struct FontOrStyleRef
 
     // A child element of cs:CT_FontReference or cs:CT_StyleReference is
     // a:EG_ColorChoice. The latter is handled by ColorValueContext.
-    oox::drawingml::Color maColor; // needed for ColorValueContext
     model::ComplexColor maComplexColor; // needed for ColorValueContext
     // There's also an a:EG_ColorTransform member and a 'mods' member for
     // FontOrStyleRef. Ignore those for now. TODO
diff --git a/include/oox/drawingml/clrscheme.hxx 
b/include/oox/drawingml/clrscheme.hxx
index bddd58e0503b..11c6b96d66a9 100644
--- a/include/oox/drawingml/clrscheme.hxx
+++ b/include/oox/drawingml/clrscheme.hxx
@@ -80,7 +80,7 @@ public:
     const OUString& GetName() const { return maName; }
 
     void ToAny(css::uno::Any& rVal) const;
-    void fill(model::ColorSet& rColorSet) const;
+    void fill(::model::ColorSet& rColorSet) const;
 
 };
 
diff --git a/include/oox/drawingml/color.hxx b/include/oox/drawingml/color.hxx
index e3b0e6834e03..c875d7db4eef 100644
--- a/include/oox/drawingml/color.hxx
+++ b/include/oox/drawingml/color.hxx
@@ -22,6 +22,7 @@
 
 #include <vector>
 
+#include <unordered_map>
 #include <com/sun/star/beans/PropertyValue.hpp>
 #include <com/sun/star/uno/Sequence.hxx>
 #include <oox/helper/helper.hxx>
@@ -31,14 +32,15 @@
 #include <tools/color.hxx>
 #include <docmodel/theme/ThemeColorType.hxx>
 #include <docmodel/color/ComplexColor.hxx>
+#include <docmodel/color/Transformation.hxx>
 
 namespace oox { class GraphicHelper; }
 
 namespace oox::drawingml
 {
 
-model::ThemeColorType schemeTokenToThemeColorType(sal_uInt32 nToken);
-model::ThemeColorType schemeNameToThemeColorType(OUString const& rSchemeName);
+::model::ThemeColorType schemeTokenToThemeColorType(sal_uInt32 nToken);
+::model::ThemeColorType schemeNameToThemeColorType(OUString const& 
rSchemeName);
 
 class OOX_DLLPUBLIC Color
 {
@@ -89,9 +91,9 @@ public:
     void                assignIfUsed( const Color& rColor ) { if( 
rColor.isUsed() ) *this = rColor; }
 
     /** Returns true, if the color is initialized. */
-    bool                isUsed() const { return meMode != ColorMode::Unused; }
+    bool                isUsed() const { return meMode != 
::model::ColorType::Unused; }
     /** Returns true, if the color is a placeholder color in theme style 
lists. */
-    bool                isPlaceHolder() const { return meMode == 
ColorMode::PlaceHolder; }
+    bool                isPlaceHolder() const { return meMode == 
::model::ColorType::Placeholder; }
     /** Returns the final RGB color value.
         @param nPhClr  Actual color for the phClr placeholder color used in 
theme style lists. */
     ::Color             getColor( const GraphicHelper& rGraphicHelper, ::Color 
nPhClr = API_RGB_TRANSPARENT ) const;
@@ -108,12 +110,12 @@ public:
     sal_Int16           getLumMod() const;
     sal_Int16           getLumOff() const;
 
-    model::ThemeColorType getThemeColorType() const
+    ::model::ThemeColorType getThemeColorType() const
     {
         return meThemeColorType;
     }
 
-    model::ComplexColor createComplexColor(const GraphicHelper& 
rGraphicHelper, sal_Int16 nPhClrTheme) const;
+    ::model::ComplexColor createComplexColor(const GraphicHelper& 
rGraphicHelper, sal_Int16 nPhClrTheme) const;
 
     /** Returns the unaltered list of transformations for interoperability 
purposes */
     const css::uno::Sequence< css::beans::PropertyValue >& 
getTransformations() const { return maInteropTransformations;}
@@ -124,11 +126,13 @@ public:
     static sal_Int32    getColorTransformationToken( std::u16string_view sName 
);
     /** Translates between ColorMap token names and the corresponding token */
     static sal_Int32    getColorMapToken(std::u16string_view sName);
+    // Translate from color transformation token to docmodel enumeration value
+    static ::model::TransformationType getTransformationType(sal_Int32 
nElement);
 
     /// Compares this color with rOther.
     bool equals(const Color& rOther, const GraphicHelper& rGraphicHelper, 
::Color nPhClr) const;
 
-    model::ComplexColor getComplexColor() const;
+    ::model::ComplexColor getComplexColor() const;
 
     bool operator==(const Color&) const;
 
@@ -144,38 +148,15 @@ private:
     void                toHsl() const;
 
 private:
-    enum class ColorMode
-    {
-        Unused,              /// Color is not used, or undefined.
-        AbsoluteRgb,         /// Absolute RGB (r/g/b: 0...255).
-        RelativeRgb,         /// Relative RGB (r/g/b: 0...100000).
-        Hsl,                 /// HSL (hue: 0...21600000, sat/lum: 0...100000).
-        Scheme,              /// Color from scheme.
-        ApplicationPalette,  /// Color from application defined palette.
-        SystemPalette,       /// Color from system palette.
-        PlaceHolder,         /// Placeholder color in theme style lists.
-        Finalized            /// Finalized RGB color.
-    };
-
-    struct Transformation
-    {
-        sal_Int32           mnToken;
-        sal_Int32           mnValue;
-
-        explicit            Transformation( sal_Int32 nToken, sal_Int32 nValue 
) : mnToken( nToken ), mnValue( nValue ) {}
-
-        bool operator==(const Transformation&) const noexcept = default;
-    };
 
-    mutable ColorMode   meMode;         /// Current color mode.
-    mutable std::vector< Transformation >
-                        maTransforms;  /// Color transformations.
+    mutable ::model::ColorType meMode; /// Current color mode.
+    mutable std::vector<::model::Transformation> maTransforms;  /// Color 
transformations.
     mutable sal_Int32   mnC1;           /// Red, red%, hue, scheme token, 
palette index, system token, or final RGB.
     mutable sal_Int32   mnC2;           /// Green, green%, saturation, or 
system default RGB.
     mutable sal_Int32   mnC3;           /// Blue, blue%, or luminance.
     sal_Int32           mnAlpha;        /// Alpha value (color opacity).
     OUString            msSchemeName;   /// Scheme name from the a:schemeClr 
element for interoperability purposes
-    model::ThemeColorType meThemeColorType;
+    ::model::ThemeColorType meThemeColorType;
     css::uno::Sequence< css::beans::PropertyValue >
                         maInteropTransformations;   /// Unaltered list of 
transformations for interoperability purposes
 };
diff --git a/oox/inc/drawingml/colorchoicecontext.hxx 
b/oox/inc/drawingml/colorchoicecontext.hxx
index ddd720e3c53d..c3736bfbb46b 100644
--- a/oox/inc/drawingml/colorchoicecontext.hxx
+++ b/oox/inc/drawingml/colorchoicecontext.hxx
@@ -31,10 +31,10 @@ class Color;
 
 /** Context handler for the different color value elements (a:scrgbClr,
     a:srgbClr, a:hslClr, a:sysClr, a:schemeClr, a:prstClr). */
-class ColorValueContext final : public ::oox::core::ContextHandler2
+class ColorValueContext : public ::oox::core::ContextHandler2
 {
 public:
-    explicit ColorValueContext(::oox::core::ContextHandler2Helper const & 
rParent, Color& rColor, model::ComplexColor* pComplexColor = nullptr);
+    explicit ColorValueContext(::oox::core::ContextHandler2Helper const & 
rParent, Color* rColor, ::model::ComplexColor* pComplexColor = nullptr);
 
     virtual void onStartElement(const ::oox::AttributeList& rAttribs) override;
 
@@ -42,8 +42,8 @@ public:
         sal_Int32 nElement, const ::oox::AttributeList& rAttribs) override;
 
 private:
-    Color& mrColor;
-    model::ComplexColor* mpComplexColor;
+    Color* mpColor;
+    ::model::ComplexColor* mpComplexColor;
 };
 
 
@@ -52,16 +52,16 @@ private:
 class ColorContext : public ::oox::core::ContextHandler2
 {
 public:
-    explicit ColorContext(::oox::core::ContextHandler2Helper const & rParent, 
Color& rColor, model::ComplexColor* pComplexColor = nullptr);
+    explicit ColorContext(::oox::core::ContextHandler2Helper const & rParent, 
Color* pColor, ::model::ComplexColor* pComplexColor = nullptr);
 
     virtual ::oox::core::ContextHandlerRef onCreateContext(
         sal_Int32 nElement, const ::oox::AttributeList& rAttribs) override;
 
 private:
-    Color& mrColor;
+    Color* mpColor;
 
 protected:
-    model::ComplexColor* mpComplexColor;
+    ::model::ComplexColor* mpComplexColor;
 };
 
 /// Same as ColorContext, but handles multiple colors.
diff --git a/oox/inc/drawingml/misccontexts.hxx 
b/oox/inc/drawingml/misccontexts.hxx
index 1b7f05444ac7..8fc1bb7e12fc 100644
--- a/oox/inc/drawingml/misccontexts.hxx
+++ b/oox/inc/drawingml/misccontexts.hxx
@@ -24,6 +24,7 @@
 
 #include <drawingml/fillproperties.hxx>
 #include <docmodel/theme/FormatScheme.hxx>
+#include <docmodel/color/ComplexColor.hxx>
 
 namespace oox::drawingml
 {
@@ -33,7 +34,7 @@ class SolidFillContext final : public ColorContext
 {
 public:
     explicit SolidFillContext(::oox::core::ContextHandler2Helper const & 
rParent,
-        FillProperties& rFillProps, model::SolidFill* pSolidFill);
+        FillProperties& rFillProps, ::model::SolidFill* pSolidFill);
     ~SolidFillContext();
 };
 
@@ -44,7 +45,7 @@ class GradientFillContext final : public 
::oox::core::ContextHandler2
 public:
     explicit GradientFillContext(::oox::core::ContextHandler2Helper const & 
rParent,
         const ::oox::AttributeList& rAttribs, GradientFillProperties& 
rGradientProps,
-        model::GradientFill* pGradientFill);
+        ::model::GradientFill* pGradientFill);
 
     virtual ::oox::core::ContextHandlerRef
                         onCreateContext(
@@ -52,7 +53,7 @@ public:
                             const ::oox::AttributeList& rAttribs ) override;
 
 private:
-    model::GradientFill* mpGradientFill;
+    ::model::GradientFill* mpGradientFill;
     GradientFillProperties& mrGradientProps;
 };
 
@@ -62,7 +63,7 @@ class PatternFillContext final : public 
::oox::core::ContextHandler2
 public:
     explicit PatternFillContext(::oox::core::ContextHandler2Helper const& 
rParent,
                             const ::oox::AttributeList& rAttribs, 
PatternFillProperties& rPatternProps,
-                            model::PatternFill* pPatternFill);
+                            ::model::PatternFill* pPatternFill);
 
     virtual ::oox::core::ContextHandlerRef
                         onCreateContext(
@@ -70,7 +71,7 @@ public:
                             const ::oox::AttributeList& rAttribs ) override;
 
 private:
-    model::PatternFill* mpPatternFill;
+    ::model::PatternFill* mpPatternFill;
     PatternFillProperties& mrPatternProps;
 };
 
@@ -103,7 +104,7 @@ public:
     explicit            BlipExtensionContext(
                             ::oox::core::ContextHandler2Helper const & rParent,
                                 BlipFillProperties& rBlipProps,
-                                model::BlipFill* pBlipFill);
+                                ::model::BlipFill* pBlipFill);
     virtual             ~BlipExtensionContext() override;
 
     virtual ::oox::core::ContextHandlerRef
@@ -113,7 +114,7 @@ public:
 
 private:
     BlipFillProperties& mrBlipProps;
-    model::BlipFill* mpBlipFill;
+    ::model::BlipFill* mpBlipFill;
 };
 
 
@@ -144,7 +145,7 @@ class ColorChangeContext final : public 
::oox::core::ContextHandler2
 {
 public:
     explicit ColorChangeContext(::oox::core::ContextHandler2Helper const & 
rParent, const ::oox::AttributeList& rAttribs,
-                            BlipFillProperties& rBlipProps, model::BlipFill* 
pBlipFill);
+                            BlipFillProperties& rBlipProps, ::model::BlipFill* 
pBlipFill);
     virtual ~ColorChangeContext() override;
 
     virtual ::oox::core::ContextHandlerRef
@@ -153,7 +154,7 @@ public:
                             const ::oox::AttributeList& rAttribs ) override;
 
 private:
-    model::BlipFill* mpBlipFill;
+    ::model::BlipFill* mpBlipFill;
     BlipFillProperties& mrBlipProps;
     bool mbUseAlpha;
 };
@@ -164,7 +165,7 @@ class BlipContext final : public 
::oox::core::ContextHandler2
 {
 public:
     explicit BlipContext(::oox::core::ContextHandler2Helper const & rParent, 
const ::oox::AttributeList& rAttribs,
-                        BlipFillProperties& rBlipProps, model::BlipFill* 
pBlipFill);
+                        BlipFillProperties& rBlipProps, ::model::BlipFill* 
pBlipFill);
 
     virtual ::oox::core::ContextHandlerRef
                         onCreateContext(
@@ -172,7 +173,7 @@ public:
                             const ::oox::AttributeList& rAttribs ) override;
 
 private:
-    model::BlipFill* mpBlipFill;
+    ::model::BlipFill* mpBlipFill;
     BlipFillProperties& mrBlipProps;
 };
 
@@ -181,7 +182,7 @@ class BlipFillContext final : public 
::oox::core::ContextHandler2
 {
 public:
     explicit BlipFillContext(::oox::core::ContextHandler2Helper const & 
rParent, const ::oox::AttributeList& rAttribs,
-                            BlipFillProperties& rBlipProps, model::BlipFill* 
pBlipFill);
+                            BlipFillProperties& rBlipProps, ::model::BlipFill* 
pBlipFill);
 
     virtual ::oox::core::ContextHandlerRef
                         onCreateContext(
@@ -189,7 +190,7 @@ public:
                             const ::oox::AttributeList& rAttribs ) override;
 
 private:
-    model::BlipFill* mpBlipFill;
+    ::model::BlipFill* mpBlipFill;
     BlipFillProperties& mrBlipProps;
 };
 
@@ -213,11 +214,11 @@ public:
                             sal_Int32 nElement,
                             const ::oox::AttributeList& rAttribs,
                             FillProperties& rFillProps,
-                            model::FillStyle* pFillStyle);
+                            ::model::FillStyle* pFillStyle);
 
 private:
     FillProperties& mrFillProps;
-    model::FillStyle maFillStyle;
+    ::model::FillStyle maFillStyle;
 };
 
 /** Context handler for elements that contain a fill property element
@@ -232,11 +233,12 @@ class SimpleFillPropertiesContext final : private 
FillProperties, public FillPro
 public:
     explicit            SimpleFillPropertiesContext(
                             ::oox::core::ContextHandler2Helper const & rParent,
-                            Color& rColor );
+                            ::model::ComplexColor& rColor, Color *pOOXColor);
     virtual             ~SimpleFillPropertiesContext() override;
 
 private:
-    Color&              mrColor;
+    ::model::ComplexColor& mrColor;
+    Color* mpOOXColor;
 };
 
 } // namespace oox::drawingml
diff --git a/oox/inc/drawingml/textcharacterproperties.hxx 
b/oox/inc/drawingml/textcharacterproperties.hxx
index 2ee1f1b5b4c2..618d4c27722a 100644
--- a/oox/inc/drawingml/textcharacterproperties.hxx
+++ b/oox/inc/drawingml/textcharacterproperties.hxx
@@ -44,8 +44,8 @@ struct TextCharacterProperties
     TextFont            maComplexFont;
     TextFont            maComplexThemeFont;
     TextFont            maSymbolFont;
-    Color               maUnderlineColor;
-    Color               maHighlightColor;
+    model::ComplexColor maUnderlineColor;
+    model::ComplexColor maHighlightColor;
     std::optional< OUString > moLang;
     std::optional< sal_Int32 > moHeight;
     /// If a font scale has to be applied manually to moHeight.
@@ -61,6 +61,7 @@ struct TextCharacterProperties
     std::optional< bool >    moUnderlineFillFollowText;
     std::optional<LineProperties> moTextOutlineProperties;
 
+    Color maHighlightOOXColor;
     FillProperties      maFillProperties;
     /// Set if there was a property set that alters run visually during import
     bool mbHasVisualRunProperties;
diff --git a/oox/source/drawingml/chart/stylefragment.cxx 
b/oox/source/drawingml/chart/stylefragment.cxx
index b93d983ca6f9..90f3fdcc7481 100644
--- a/oox/source/drawingml/chart/stylefragment.cxx
+++ b/oox/source/drawingml/chart/stylefragment.cxx
@@ -121,7 +121,7 @@ ContextHandlerRef 
StyleReferenceContext::onCreateContext(sal_Int32 nElement,
             case A_TOKEN(sysClr):
             case A_TOKEN(schemeClr):
             case A_TOKEN(prstClr):
-                return new ColorValueContext(*this, mrModel.maColor, 
&mrModel.maComplexColor);
+                return new ColorValueContext(*this, nullptr, 
&mrModel.maComplexColor);
         }
     return nullptr;
 }
@@ -153,7 +153,7 @@ ContextHandlerRef 
FontReferenceContext::onCreateContext(sal_Int32 nElement,
             case A_TOKEN(sysClr):
             case A_TOKEN(schemeClr):
             case A_TOKEN(prstClr):
-                return new ColorValueContext(*this, mrModel.maColor, 
&mrModel.maComplexColor);
+                return new ColorValueContext(*this, nullptr, 
&mrModel.maComplexColor);
         }
     return nullptr;
 }
diff --git a/oox/source/drawingml/clrschemecontext.cxx 
b/oox/source/drawingml/clrschemecontext.cxx
index 994a15b48408..55e6f152107c 100644
--- a/oox/source/drawingml/clrschemecontext.cxx
+++ b/oox/source/drawingml/clrschemecontext.cxx
@@ -56,7 +56,7 @@ clrMapContext::clrMapContext( ContextHandler2Helper const & 
rParent,
 }
 
 clrSchemeColorContext::clrSchemeColorContext(ContextHandler2Helper const & 
rParent, ClrScheme& rClrScheme, model::ColorSet& rColorSet, sal_Int32 
nColorToken)
-    : ColorContext(rParent, *this, nullptr)
+    : ColorContext(rParent, this, nullptr)
     , mrClrScheme(rClrScheme)
     , mrColorSet(rColorSet)
     , mnColorToken(nColorToken)
diff --git a/oox/source/drawingml/color.cxx b/oox/source/drawingml/color.cxx
index 063bfc7534a6..e366af32900f 100644
--- a/oox/source/drawingml/color.cxx
+++ b/oox/source/drawingml/color.cxx
@@ -290,7 +290,7 @@ model::ThemeColorType 
schemeTokenToThemeColorType(sal_uInt32 nToken)
 }
 
 Color::Color() :
-    meMode( ColorMode::Unused ),
+    meMode(model::ColorType::Unused),
     mnC1( 0 ),
     mnC2( 0 ),
     mnC3( 0 ),
@@ -349,7 +349,7 @@ bool Color::operator==(const Color& rhs) const
 
 void Color::setUnused()
 {
-    meMode = ColorMode::Unused;
+    meMode = model::ColorType::Unused;
 }
 
 void Color::setSrgbClr( ::Color nRgb )
@@ -360,7 +360,7 @@ void Color::setSrgbClr( ::Color nRgb )
 void Color::setSrgbClr( sal_Int32 nRgb )
 {
     OSL_ENSURE( (0 <= nRgb) && (nRgb <= 0xFFFFFF), "Color::setSrgbClr - 
invalid RGB value" );
-    meMode = ColorMode::AbsoluteRgb;
+    meMode = model::ColorType::RGB;
     lclRgbToRgbComponents( mnC1, mnC2, mnC3, ::Color(ColorTransparency, nRgb) 
);
 }
 
@@ -369,7 +369,7 @@ void Color::setScrgbClr( sal_Int32 nR, sal_Int32 nG, 
sal_Int32 nB )
     OSL_ENSURE( (0 <= nR) && (nR <= MAX_PERCENT), "Color::setScrgbClr - 
invalid red value" );
     OSL_ENSURE( (0 <= nG) && (nG <= MAX_PERCENT), "Color::setScrgbClr - 
invalid green value" );
     OSL_ENSURE( (0 <= nB) && (nB <= MAX_PERCENT), "Color::setScrgbClr - 
invalid blue value" );
-    meMode = ColorMode::RelativeRgb;
+    meMode = model::ColorType::CRGB;
     mnC1 = getLimitedValue< sal_Int32, sal_Int32 >( nR, 0, MAX_PERCENT );
     mnC2 = getLimitedValue< sal_Int32, sal_Int32 >( nG, 0, MAX_PERCENT );
     mnC3 = getLimitedValue< sal_Int32, sal_Int32 >( nB, 0, MAX_PERCENT );
@@ -380,7 +380,7 @@ void Color::setHslClr( sal_Int32 nHue, sal_Int32 nSat, 
sal_Int32 nLum )
     OSL_ENSURE( (0 <= nHue) && (nHue <= MAX_DEGREE), "Color::setHslClr - 
invalid hue value" );
     OSL_ENSURE( (0 <= nSat) && (nSat <= MAX_PERCENT), "Color::setHslClr - 
invalid saturation value" );
     OSL_ENSURE( (0 <= nLum) && (nLum <= MAX_PERCENT), "Color::setHslClr - 
invalid luminance value" );
-    meMode = ColorMode::Hsl;
+    meMode = model::ColorType::HSL;
     mnC1 = getLimitedValue< sal_Int32, sal_Int32 >( nHue, 0, MAX_DEGREE );
     mnC2 = getLimitedValue< sal_Int32, sal_Int32 >( nSat, 0, MAX_PERCENT );
     mnC3 = getLimitedValue< sal_Int32, sal_Int32 >( nLum, 0, MAX_PERCENT );
@@ -405,40 +405,79 @@ void Color::setHighlight(sal_Int32 nToken)
 void Color::setSchemeClr( sal_Int32 nToken )
 {
     OSL_ENSURE( nToken != XML_TOKEN_INVALID, "Color::setSchemeClr - invalid 
color token" );
-    meMode = (nToken == XML_phClr) ? ColorMode::PlaceHolder : 
ColorMode::Scheme;
+    meMode = (nToken == XML_phClr) ? model::ColorType::Placeholder :
+        model::ColorType::Theme;
     mnC1 = nToken;
-    if (meMode == ColorMode::Scheme)
+    if (meMode == model::ColorType::Theme)
         meThemeColorType = schemeTokenToThemeColorType(nToken);
 }
 
 void Color::setPaletteClr( sal_Int32 nPaletteIdx )
 {
     OSL_ENSURE( nPaletteIdx >= 0, "Color::setPaletteClr - invalid palette 
index" );
-    meMode = ColorMode::ApplicationPalette;
+    meMode = model::ColorType::Palette;
     mnC1 = nPaletteIdx;
 }
 
 void Color::setSysClr( sal_Int32 nToken, sal_Int32 nLastRgb )
 {
     OSL_ENSURE( (-1 <= nLastRgb) && (nLastRgb <= 0xFFFFFF), "Color::setSysClr 
- invalid RGB value" );
-    meMode = ColorMode::SystemPalette;
+    meMode = model::ColorType::System;
     mnC1 = nToken;
     mnC2 = nLastRgb;
 }
 
+model::TransformationType Color::getTransformationType( sal_Int32 nElement )
+{
+    switch( nElement ) {
+        case XML_red:       return model::TransformationType::Red;
+        case XML_redMod:    return model::TransformationType::RedMod;
+        case XML_redOff:    return model::TransformationType::RedOff;
+        case XML_green:     return model::TransformationType::Green;
+        case XML_greenMod:  return model::TransformationType::GreenMod;
+        case XML_greenOff:  return model::TransformationType::GreenOff;
+        case XML_blue:      return model::TransformationType::Blue;
+        case XML_blueMod:   return model::TransformationType::BlueMod;
+        case XML_blueOff:   return model::TransformationType::BlueOff;
+        case XML_alpha:     return model::TransformationType::Alpha;
+        case XML_alphaMod:  return model::TransformationType::AlphaMod;
+        case XML_alphaOff:  return model::TransformationType::AlphaOff;
+        case XML_hue:       return model::TransformationType::Hue;
+        case XML_hueMod:    return model::TransformationType::HueMod;
+        case XML_hueOff:    return model::TransformationType::HueOff;
+        case XML_sat:       return model::TransformationType::Sat;
+        case XML_satMod:    return model::TransformationType::SatMod;
+        case XML_satOff:    return model::TransformationType::SatOff;
+        case XML_lum:       return model::TransformationType::Lum;
+        case XML_lumMod:    return model::TransformationType::LumMod;
+        case XML_lumOff:    return model::TransformationType::LumOff;
+        case XML_shade:     return model::TransformationType::Shade;
+        case XML_tint:      return model::TransformationType::Tint;
+        case XML_gray:      return model::TransformationType::Gray;
+        case XML_comp:      return model::TransformationType::Comp;
+        case XML_inv:       return model::TransformationType::Inv;
+        case XML_gamma:     return model::TransformationType::Gamma;
+        case XML_invGamma:  return model::TransformationType::InvGamma;
+        default:            assert(false); return 
model::TransformationType::Undefined;
+    }
+}
+
 void Color::addTransformation( sal_Int32 nElement, sal_Int32 nValue )
 {
     /*  Execute alpha transformations directly, store other transformations in
         a vector, they may depend on a scheme base color which will be resolved
         in Color::getColor(). */
-    sal_Int32 nToken = getBaseToken( nElement );
-    switch( nToken )
+    const sal_Int32 nToken = getBaseToken( nElement );
+    const model::TransformationType eType = getTransformationType(nToken);
+
+    switch(eType)
     {
-        case XML_alpha:     lclSetValue( mnAlpha, nValue ); break;
-        case XML_alphaMod:  lclModValue( mnAlpha, nValue ); break;
-        case XML_alphaOff:  lclOffValue( mnAlpha, nValue ); break;
-        default:            maTransforms.emplace_back( nToken, nValue );
+        case model::TransformationType::Alpha: lclSetValue( mnAlpha, nValue ); 
break;
+        case model::TransformationType::AlphaMod: lclModValue( mnAlpha, nValue 
); break;
+        case model::TransformationType::AlphaOff: lclOffValue( mnAlpha, nValue 
); break;
+        default: maTransforms.emplace_back(eType, nValue);
     }
+
     sal_Int32 nSize = maInteropTransformations.getLength();
     maInteropTransformations.realloc(nSize + 1);
     auto pInteropTransformations = maInteropTransformations.getArray();
@@ -450,9 +489,9 @@ void Color::addChartTintTransformation( double fTint )
 {
     sal_Int32 nValue = getLimitedValue< sal_Int32, double >( fTint * 
MAX_PERCENT + 0.5, -MAX_PERCENT, MAX_PERCENT );
     if( nValue < 0 )
-        maTransforms.emplace_back( XML_shade, nValue + MAX_PERCENT );
+        maTransforms.emplace_back(model::TransformationType::Shade, nValue + 
MAX_PERCENT);
     else if( nValue > 0 )
-        maTransforms.emplace_back( XML_tint, MAX_PERCENT - nValue );
+        maTransforms.emplace_back(model::TransformationType::Tint, MAX_PERCENT 
- nValue);
 }
 
 void Color::addExcelTintTransformation(double fTint)
@@ -460,12 +499,12 @@ void Color::addExcelTintTransformation(double fTint)
     sal_Int32 nValue = std::round(std::abs(fTint) * 100'000.0);
     if (fTint > 0.0)
     {
-        maTransforms.emplace_back(XML_lumMod, 100'000 - nValue);
-        maTransforms.emplace_back(XML_lumOff, nValue);
+        maTransforms.emplace_back(model::TransformationType::LumMod, 100'000 - 
nValue);
+        maTransforms.emplace_back(model::TransformationType::LumOff, nValue);
     }
     else if (fTint < 0.0)
     {
-        maTransforms.emplace_back(XML_lumMod, 100'000 - nValue);
+        maTransforms.emplace_back(model::TransformationType::LumMod, 100'000 - 
nValue);
     }
 }
 
@@ -608,16 +647,18 @@ void Color::clearTransparence()
 
 sal_Int16 Color::getTintOrShade() const
 {
-    for(auto const& aTransform : maTransforms)
+    for(const auto& aTransform : maTransforms)
     {
-        switch(aTransform.mnToken)
+        switch(aTransform.meType)
         {
-            case XML_tint:
+            case model::TransformationType::Tint:
                 // from 1000th percent to 100th percent...
                 return aTransform.mnValue/10;
-            case XML_shade:
+            case model::TransformationType::Shade:
                 // from 1000th percent to 100th percent...
                 return -aTransform.mnValue/10;
+            default:
+                break;
         }
     }
     return 0;
@@ -627,7 +668,7 @@ sal_Int16 Color::getLumMod() const
 {
     for (const auto& rTransform : maTransforms)
     {
-        if (rTransform.mnToken != XML_lumMod)
+        if (rTransform.meType != model::TransformationType::LumMod)
         {
             continue;
         }
@@ -643,7 +684,7 @@ sal_Int16 Color::getLumOff() const
 {
     for (const auto& rTransform : maTransforms)
     {
-        if (rTransform.mnToken != XML_lumOff)
+        if (rTransform.meType != model::TransformationType::LumOff)
         {
             continue;
         }
@@ -683,77 +724,77 @@ model::ComplexColor Color::getComplexColor() const
     const sal_Int32 nTempC1 = mnC1;
     const sal_Int32 nTempC2 = mnC2;
     const sal_Int32 nTempC3 = mnC3;
-    const ColorMode eTempMode = meMode;
+    const model::ColorType eTempMode = meMode;
 
     switch( meMode )
     {
-        case ColorMode::Unused:  mnC1 = sal_Int32(API_RGB_TRANSPARENT); break;
+        case model::ColorType::Unused: mnC1 = sal_Int32(API_RGB_TRANSPARENT); 
break;
 
-        case ColorMode::AbsoluteRgb:     break;  // nothing to do
-        case ColorMode::RelativeRgb:    break;  // nothing to do
-        case ColorMode::Hsl:     break;  // nothing to do
+        case model::ColorType::RGB: break; // nothing to do
+        case model::ColorType::CRGB: break; // nothing to do
+        case model::ColorType::HSL: break; // nothing to do
 
-        case ColorMode::Scheme:
+        case model::ColorType::Theme:
             setResolvedRgb( rGraphicHelper.getSchemeColor( mnC1 ) );
             break;
-        case ColorMode::ApplicationPalette:
+        case model::ColorType::Palette:
             setResolvedRgb( rGraphicHelper.getPaletteColor( mnC1 ) );
             break;
-        case ColorMode::SystemPalette:
+        case model::ColorType::System:
             setResolvedRgb( rGraphicHelper.getSystemColor( mnC1, 
::Color(ColorTransparency, mnC2) ) );
             break;
-        case ColorMode::PlaceHolder:
+        case model::ColorType::Placeholder:
             setResolvedRgb( nPhClr );
             break;
 
-        case ColorMode::Finalized:
+        case model::ColorType::Finalized:
             return ::Color(ColorTransparency, mnC1);
     }
 
     // if color is UNUSED or turns to UNUSED in setResolvedRgb, do not perform 
transformations
-    if( meMode != ColorMode::Unused )
+    if (meMode != model::ColorType::Unused)
     {
         for (auto const& transform : maTransforms)
         {
-            switch( transform.mnToken )
+            switch (transform.meType)
             {
-                case XML_red:       toCrgb(); lclSetValue( mnC1, 
transform.mnValue );    break;
-                case XML_redMod:    toCrgb(); lclModValue( mnC1, 
transform.mnValue );    break;
-                case XML_redOff:    toCrgb(); lclOffValue( mnC1, 
transform.mnValue );    break;
-                case XML_green:     toCrgb(); lclSetValue( mnC2, 
transform.mnValue );    break;
-                case XML_greenMod:  toCrgb(); lclModValue( mnC2, 
transform.mnValue );    break;
-                case XML_greenOff:  toCrgb(); lclOffValue( mnC2, 
transform.mnValue );    break;
-                case XML_blue:      toCrgb(); lclSetValue( mnC3, 
transform.mnValue );    break;
-                case XML_blueMod:   toCrgb(); lclModValue( mnC3, 
transform.mnValue );    break;
-                case XML_blueOff:   toCrgb(); lclOffValue( mnC3, 
transform.mnValue );    break;
-
-                case XML_hue:       toHsl(); lclSetValue( mnC1, 
transform.mnValue, MAX_DEGREE ); break;
-                case XML_hueMod:    toHsl(); lclModValue( mnC1, 
transform.mnValue, MAX_DEGREE ); break;
-                case XML_hueOff:    toHsl(); lclOffValue( mnC1, 
transform.mnValue, MAX_DEGREE ); break;
-                case XML_sat:       toHsl(); lclSetValue( mnC2, 
transform.mnValue );             break;
-                case XML_satMod:    toHsl(); lclModValue( mnC2, 
transform.mnValue );             break;
-                case XML_satOff:    toHsl(); lclOffValue( mnC2, 
transform.mnValue );             break;
-
-                case XML_lum:
+                case model::TransformationType::Red: toCrgb(); lclSetValue( 
mnC1, transform.mnValue ); break;
+                case model::TransformationType::RedMod: toCrgb(); lclModValue( 
mnC1, transform.mnValue ); break;
+                case model::TransformationType::RedOff: toCrgb(); lclOffValue( 
mnC1, transform.mnValue ); break;
+                case model::TransformationType::Green: toCrgb(); lclSetValue( 
mnC2, transform.mnValue ); break;
+                case model::TransformationType::GreenMod: toCrgb(); 
lclModValue( mnC2, transform.mnValue ); break;
+                case model::TransformationType::GreenOff: toCrgb(); 
lclOffValue( mnC2, transform.mnValue ); break;
+                case model::TransformationType::Blue: toCrgb(); lclSetValue( 
mnC3, transform.mnValue ); break;
+                case model::TransformationType::BlueMod: toCrgb(); 
lclModValue( mnC3, transform.mnValue ); break;
+                case model::TransformationType::BlueOff: toCrgb(); 
lclOffValue( mnC3, transform.mnValue ); break;
+
+                case model::TransformationType::Hue: toHsl(); lclSetValue( 
mnC1, transform.mnValue, MAX_DEGREE ); break;
+                case model::TransformationType::HueMod: toHsl(); lclModValue( 
mnC1, transform.mnValue, MAX_DEGREE ); break;
+                case model::TransformationType::HueOff: toHsl(); lclOffValue( 
mnC1, transform.mnValue, MAX_DEGREE ); break;
+                case model::TransformationType::Sat: toHsl(); lclSetValue( 
mnC2, transform.mnValue ); break;
+                case model::TransformationType::SatMod: toHsl(); lclModValue( 
mnC2, transform.mnValue ); break;
+                case model::TransformationType::SatOff:  toHsl(); lclOffValue( 
mnC2, transform.mnValue ); break;
+
+                case model::TransformationType::Lum:
                     toHsl();
                     lclSetValue( mnC3, transform.mnValue );
                     // if color changes to black or white, it will stay gray 
if luminance changes again
                     if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0;
                 break;
-                case XML_lumMod:
+                case model::TransformationType::LumMod:
                     toHsl();
                     lclModValue( mnC3, transform.mnValue );
                     // if color changes to black or white, it will stay gray 
if luminance changes again
                     if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0;
                 break;
-                case XML_lumOff:
+                case model::TransformationType::LumOff:
                     toHsl();
                     lclOffValue( mnC3, transform.mnValue );
                     // if color changes to black or white, it will stay gray 
if luminance changes again
                     if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0;
                 break;
 
-                case XML_shade:
+                case model::TransformationType::Shade:
                     // shade: 0% = black, 100% = original color
                     toCrgb();
                     OSL_ENSURE( (0 <= transform.mnValue) && (transform.mnValue 
<= MAX_PERCENT), "Color::getColor - invalid shade value" );
@@ -765,7 +806,7 @@ model::ComplexColor Color::getComplexColor() const
                         mnC3 = static_cast< sal_Int32 >( mnC3 * fFactor );
                     }
                 break;
-                case XML_tint:
+                case model::TransformationType::Tint:
                     // tint: 0% = white, 100% = original color
                     toCrgb();
                     OSL_ENSURE( (0 <= transform.mnValue) && (transform.mnValue 
<= MAX_PERCENT), "Color::getColor - invalid tint value" );
@@ -778,18 +819,18 @@ model::ComplexColor Color::getComplexColor() const
                     }
                 break;
 
-                case XML_gray:
+                case model::TransformationType::Gray:
                     // change color to gray, weighted RGB: 22% red, 72% green, 
6% blue
                     toRgb();
                     mnC1 = mnC2 = mnC3 = (mnC1 * 22 + mnC2 * 72 + mnC3 * 6) / 
100;
                 break;
 
-                case XML_comp:
+                case model::TransformationType::Comp:
                     // comp: rotate hue by 180 degrees, do not change lum/sat
                     toHsl();
                     mnC1 = (mnC1 + (180 * PER_DEGREE)) % MAX_DEGREE;
                 break;
-                case XML_inv:
+                case model::TransformationType::Inv:
                     // invert percentual RGB values
                     toCrgb();
                     mnC1 = MAX_PERCENT - mnC1;
@@ -797,20 +838,28 @@ model::ComplexColor Color::getComplexColor() const
                     mnC3 = MAX_PERCENT - mnC3;
                 break;
 
-                case XML_gamma:
+                case model::TransformationType::Gamma:
                     // increase gamma of color
                     toCrgb();
                     mnC1 = lclGamma( mnC1, INC_GAMMA );
                     mnC2 = lclGamma( mnC2, INC_GAMMA );
                     mnC3 = lclGamma( mnC3, INC_GAMMA );
                 break;
-                case XML_invGamma:
+                case model::TransformationType::InvGamma:
                     // decrease gamma of color
                     toCrgb();
                     mnC1 = lclGamma( mnC1, DEC_GAMMA );
                     mnC2 = lclGamma( mnC2, DEC_GAMMA );
                     mnC3 = lclGamma( mnC3, DEC_GAMMA );
                 break;
+                case model::TransformationType::Alpha:
+                case model::TransformationType::AlphaMod:
+                case model::TransformationType::AlphaOff:
+                    // nothing to do
+                    break;
+                default:
+                    assert(false);
+                    break;
             }
         }
 
@@ -822,7 +871,7 @@ model::ComplexColor Color::getComplexColor() const
             mnC1 |= static_cast<sal_Int32>(255.0 * (MAX_PERCENT - mnAlpha) / 
MAX_PERCENT) << 24;
         }
     }
-    else // if( meMode != ColorMode::Unused )
+    else // if( meMode != model::ColorType::Unused )
     {
         mnC1 = sal_Int32(API_RGB_TRANSPARENT);
     }
@@ -830,7 +879,7 @@ model::ComplexColor Color::getComplexColor() const
     sal_Int32 nRet = mnC1;
     // Restore the original values when the color depends on one of the input
     // parameters (rGraphicHelper or nPhClr)
-    if( eTempMode >= ColorMode::Scheme && eTempMode <= ColorMode::PlaceHolder )
+    if (eTempMode >= model::ColorType::Theme && eTempMode <= 
model::ColorType::Placeholder)
     {
         mnC1 = nTempC1;
         mnC2 = nTempC2;
@@ -839,9 +888,9 @@ model::ComplexColor Color::getComplexColor() const
     }
     else
     {
-        meMode = ColorMode::Finalized;
+        meMode = model::ColorType::Finalized;
     }
-    if( meMode == ColorMode::Finalized )
+    if (meMode == model::ColorType::Finalized)
         maTransforms.clear();
     return ::Color(ColorTransparency, nRet);
 }
@@ -865,17 +914,17 @@ sal_Int16 Color::getSchemeColorIndex() const
 model::ComplexColor Color::createComplexColor(const GraphicHelper& 
/*rGraphicHelper*/, sal_Int16 nPhClrTheme) const
 {
     model::ComplexColor aNewComplexColor;
-    if (meMode == ColorMode::PlaceHolder)
+    if (meMode == model::ColorType::Placeholder)
     {
         auto eTheme = model::convertToThemeColorType(nPhClrTheme);
         aNewComplexColor.setThemeColor(eTheme);
     }
-    else if (meMode == ColorMode::Scheme)
+    else if (meMode == model::ColorType::Theme)
     {
         auto eTheme = getThemeColorType();
         aNewComplexColor.setThemeColor(eTheme);
     }
-    else if (meMode == ColorMode::AbsoluteRgb)
+    else if (meMode == model::ColorType::RGB)
     {
         ::Color aColor(ColorTransparency, lclRgbComponentsToRgb(mnC1, mnC2, 
mnC3));
         aNewComplexColor = model::ComplexColor::createRGB(aColor);
@@ -890,24 +939,27 @@ model::ComplexColor Color::createComplexColor(const 
GraphicHelper& /*rGraphicHel
     {
         sal_Int16 nValue = sal_Int16(aTransform.mnValue / 10);
 
-        switch (aTransform.mnToken)
+        switch (aTransform.meType)
         {
-            case XML_lumMod:
+            case model::TransformationType::LumMod:
                 if (nValue != 10'000)
                     
aNewComplexColor.addTransformation({model::TransformationType::LumMod, nValue});
                 break;
-            case XML_lumOff:
+            case model::TransformationType::LumOff:
                 if (nValue != 0)
                     
aNewComplexColor.addTransformation({model::TransformationType::LumOff, nValue});
                 break;
-            case XML_tint:
+            case model::TransformationType::Tint:
                 if (nValue != 0)
                     
aNewComplexColor.addTransformation({model::TransformationType::Tint, nValue});
                 break;
-            case XML_shade:
+            case model::TransformationType::Shade:
                 if (nValue != 0)
                     
aNewComplexColor.addTransformation({model::TransformationType::Shade, nValue});
                 break;
+            default:
+                // nothing to do
+                break;
         }
     }
 
@@ -918,7 +970,7 @@ model::ComplexColor Color::createComplexColor(const 
GraphicHelper& /*rGraphicHel
 
 void Color::setResolvedRgb( ::Color nRgb ) const
 {
-    meMode = (sal_Int32(nRgb) < 0) ? ColorMode::Unused : 
ColorMode::AbsoluteRgb;
+    meMode = (sal_Int32(nRgb) < 0) ? model::ColorType::Unused : 
model::ColorType::RGB;
     lclRgbToRgbComponents( mnC1, mnC2, mnC3, nRgb );
 }
 
@@ -926,18 +978,18 @@ void Color::toRgb() const
 {
     switch( meMode )
     {
-        case ColorMode::AbsoluteRgb:
+        case model::ColorType::RGB:
             // nothing to do
         break;
-        case ColorMode::RelativeRgb:
-            meMode = ColorMode::AbsoluteRgb;
+        case model::ColorType::CRGB:
+            meMode = model::ColorType::RGB;
             mnC1 = lclCrgbCompToRgbComp( lclGamma( mnC1, INC_GAMMA ) );
             mnC2 = lclCrgbCompToRgbComp( lclGamma( mnC2, INC_GAMMA ) );
             mnC3 = lclCrgbCompToRgbComp( lclGamma( mnC3, INC_GAMMA ) );
         break;
-        case ColorMode::Hsl:
+        case model::ColorType::HSL:
         {
-            meMode = ColorMode::AbsoluteRgb;
+            meMode = model::ColorType::RGB;
             double fR = 0.0, fG = 0.0, fB = 0.0;
             if( (mnC2 == 0) || (mnC3 == MAX_PERCENT) )
             {
@@ -991,16 +1043,16 @@ void Color::toCrgb() const
 {
     switch( meMode )
     {
-        case ColorMode::Hsl:
+        case model::ColorType::HSL:
             toRgb();
             [[fallthrough]];
-        case ColorMode::AbsoluteRgb:
-            meMode = ColorMode::RelativeRgb;
+        case model::ColorType::RGB:
+            meMode = model::ColorType::CRGB;
             mnC1 = lclGamma( lclRgbCompToCrgbComp( mnC1 ), DEC_GAMMA );
             mnC2 = lclGamma( lclRgbCompToCrgbComp( mnC2 ), DEC_GAMMA );
             mnC3 = lclGamma( lclRgbCompToCrgbComp( mnC3 ), DEC_GAMMA );
         break;
-        case ColorMode::RelativeRgb:
+        case model::ColorType::CRGB:
             // nothing to do
         break;
         default:
@@ -1012,12 +1064,12 @@ void Color::toHsl() const
 {
     switch( meMode )
     {
-        case ColorMode::RelativeRgb:
+        case model::ColorType::CRGB:
             toRgb();
             [[fallthrough]];
-        case ColorMode::AbsoluteRgb:
+        case model::ColorType::RGB:
         {
-            meMode = ColorMode::Hsl;
+            meMode = model::ColorType::HSL;
             double fR = static_cast< double >( mnC1 ) / 255.0;  // red [0.0, 
1.0]
             double fG = static_cast< double >( mnC2 ) / 255.0;  // green [0.0, 
1.0]
             double fB = static_cast< double >( mnC3 ) / 255.0;  // blue [0.0, 
1.0]
@@ -1049,7 +1101,7 @@ void Color::toHsl() const
                 mnC2 = static_cast< sal_Int32 >( fD / (2.0 - fMax - fMin) * 
MAX_PERCENT + 0.5 );
         }
         break;
-        case ColorMode::Hsl:
+        case model::ColorType::HSL:
             // nothing to do
         break;
         default:
diff --git a/oox/source/drawingml/colorchoicecontext.cxx 
b/oox/source/drawingml/colorchoicecontext.cxx
index 714fbc073d78..41c2180a1a87 100644
--- a/oox/source/drawingml/colorchoicecontext.cxx
+++ b/oox/source/drawingml/colorchoicecontext.cxx
@@ -67,43 +67,11 @@ constexpr auto constSystemColorMap = 
frozen::make_unordered_map<sal_Int32, model
     { XML_menuBar, model::SystemColorType::MenuBar }
 });
 
-constexpr auto constTransformTypeMap = frozen::make_unordered_map<sal_Int32, 
model::TransformationType>
-({
-    { XML_alpha, model::TransformationType::Alpha },
-    { XML_alphaMod, model::TransformationType::AlphaMod },
-    { XML_alphaOff, model::TransformationType::AlphaOff },
-    { XML_blue, model::TransformationType::Blue },
-    { XML_blueMod, model::TransformationType::BlueMod },
-    { XML_blueOff, model::TransformationType::BlueOff },
-    { XML_hue, model::TransformationType::Hue },
-    { XML_hueMod, model::TransformationType::HueMod},
-    { XML_hueOff, model::TransformationType::HueOff },
-    { XML_lum, model::TransformationType::Lum },
-    { XML_lumMod, model::TransformationType::LumMod },
-    { XML_lumOff, model::TransformationType::LumOff },
-    { XML_green, model::TransformationType::Green },
-    { XML_greenMod, model::TransformationType::GreenMod },
-    { XML_greenOff, model::TransformationType::GreenOff },
-    { XML_red, model::TransformationType::Red },
-    { XML_redMod, model::TransformationType::RedMod },
-    { XML_redOff, model::TransformationType::RedOff },
-    { XML_sat, model::TransformationType::Sat },
-    { XML_satMod, model::TransformationType::SatMod },
-    { XML_satOff, model::TransformationType::SatMod },
-    { XML_shade, model::TransformationType::Shade },
-    { XML_tint, model::TransformationType::Tint },
-    { XML_comp, model::TransformationType::Comp },
-    { XML_gamma, model::TransformationType::Gamma },
-    { XML_gray, model::TransformationType::Gray },
-    { XML_inv, model::TransformationType::Inv },
-    { XML_invGamma, model::TransformationType::InvGamma }
-});
-
 }
 
-ColorValueContext::ColorValueContext(ContextHandler2Helper const & rParent, 
Color& rColor, model::ComplexColor* pComplexColor)
+ColorValueContext::ColorValueContext(ContextHandler2Helper const & rParent, 
Color* pColor, model::ComplexColor* pComplexColor)
     : ContextHandler2(rParent)
-    , mrColor(rColor)
+    , mpColor(pColor)
     , mpComplexColor(pComplexColor)
 {
 }
@@ -114,10 +82,13 @@ void ColorValueContext::onStartElement( const 
AttributeList& rAttribs )
     {
         case A_TOKEN(scrgbClr):
         {
-            mrColor.setScrgbClr(
-                rAttribs.getInteger( XML_r, 0 ),
-                rAttribs.getInteger( XML_g, 0 ),
-                rAttribs.getInteger( XML_b, 0 ) );
+            if (mpColor)
+            {
+                mpColor->setScrgbClr(
+                    rAttribs.getInteger( XML_r, 0 ),
+                    rAttribs.getInteger( XML_g, 0 ),
+                    rAttribs.getInteger( XML_b, 0 ) );
+            }
             if (mpComplexColor)
             {
                 mpComplexColor->setCRGB(
@@ -130,7 +101,7 @@ void ColorValueContext::onStartElement( const 
AttributeList& rAttribs )
 
         case A_TOKEN(srgbClr):
         {
-            mrColor.setSrgbClr(rAttribs.getIntegerHex(XML_val, 0));
+            if (mpColor) mpColor->setSrgbClr(rAttribs.getIntegerHex(XML_val, 
0));
             if (mpComplexColor)
             {
                 mpComplexColor->setRGB(rAttribs.getIntegerHex(XML_val, 0));
@@ -140,10 +111,13 @@ void ColorValueContext::onStartElement( const 
AttributeList& rAttribs )
 
         case A_TOKEN(hslClr):
         {
-            mrColor.setHslClr(
-                rAttribs.getInteger( XML_hue, 0 ),
-                rAttribs.getInteger( XML_sat, 0 ),
-                rAttribs.getInteger( XML_lum, 0 ) );
+            if (mpColor)
+            {
+                mpColor->setHslClr(
+                    rAttribs.getInteger(XML_hue, 0),
+                    rAttribs.getInteger(XML_sat, 0),
+                    rAttribs.getInteger(XML_lum, 0));
+            }
 
             if (mpComplexColor)
             {
@@ -160,7 +134,7 @@ void ColorValueContext::onStartElement( const 
AttributeList& rAttribs )
             sal_Int32 nToken = rAttribs.getToken(XML_val, XML_TOKEN_INVALID);
             sal_Int32 nLastColor = rAttribs.getIntegerHex(XML_lastClr, -1);
 
-            mrColor.setSysClr(nToken, nLastColor);
+            if (mpColor) mpColor->setSysClr(nToken, nLastColor);
 
             if (mpComplexColor)
             {
@@ -178,11 +152,11 @@ void ColorValueContext::onStartElement( const 
AttributeList& rAttribs )
         case A_TOKEN(schemeClr):
         {
             auto nToken = rAttribs.getToken(XML_val, XML_TOKEN_INVALID);
-            mrColor.setSchemeClr(nToken);
+            if (mpColor) mpColor->setSchemeClr(nToken);
             std::optional<OUString> sSchemeName = rAttribs.getString(XML_val);
             if (sSchemeName.has_value())
             {
-                mrColor.setSchemeName(*sSchemeName);
+                if (mpColor) mpColor->setSchemeName(*sSchemeName);
 
                 if (mpComplexColor)
                 {
@@ -203,7 +177,7 @@ void ColorValueContext::onStartElement( const 
AttributeList& rAttribs )
         case A_TOKEN(prstClr):
         {
             sal_Int32 nToken = rAttribs.getToken(XML_val, XML_TOKEN_INVALID);
-            mrColor.setPrstClr(nToken);
+            if (mpColor) mpColor->setPrstClr(nToken);
             if (mpComplexColor)
             {
                 // TODO - just converted to RGB for now
@@ -252,7 +226,7 @@ void ColorValueContext::onStartElement( const 
AttributeList& rAttribs )
             }
             else
                 nVal = rAttribs.getInteger(XML_val, 0);
-            mrColor.addTransformation( nElement, nVal );
+            if (mpColor) mpColor->addTransformation(nElement, nVal);
         }
         break;
         case A_TOKEN( comp ):
@@ -260,35 +234,34 @@ void ColorValueContext::onStartElement( const 
AttributeList& rAttribs )
         case A_TOKEN( gray ):
         case A_TOKEN( inv ):
         case A_TOKEN( invGamma ):
-            mrColor.addTransformation( nElement );
+            if (mpColor) mpColor->addTransformation( nElement );
         break;
     }
 
     if (mpComplexColor)
     {
-        auto aIterator = constTransformTypeMap.find(getBaseToken(nElement));
-        if (aIterator != constTransformTypeMap.end())
-        {
-            auto const& aPair = *aIterator;
-            model::TransformationType eType = aPair.second;
+        model::TransformationType eType = 
Color::getTransformationType(getBaseToken(nElement));
 
-            OUString aValueString = rAttribs.getStringDefaulted(XML_val);
-            sal_Int32 nValue = 0;
-            if (aValueString.endsWith("%"))
-                nValue = aValueString.toDouble() * PER_PERCENT;
-            else
-                nValue = rAttribs.getInteger(XML_val, 0);
+        OUString aValueString = rAttribs.getStringDefaulted(XML_val);
+        sal_Int32 nValue = 0;
+        if (aValueString.endsWith("%"))
+            nValue = aValueString.toDouble() * PER_PERCENT;
+        else
+            nValue = rAttribs.getInteger(XML_val, 0);
 
-            mpComplexColor->addTransformation({eType, sal_Int16(nValue / 10)});
-        }
+        mpComplexColor->addTransformation({eType, sal_Int16(nValue / 10)});
     }
 
     return nullptr;
 }
 
-ColorContext::ColorContext(ContextHandler2Helper const & rParent, Color& 
rColor, model::ComplexColor* pComplexColor)
+//===========
+// ColorContext
+//===========
+
+ColorContext::ColorContext(ContextHandler2Helper const & rParent, Color* 
pColor, model::ComplexColor* pComplexColor)
     : ContextHandler2(rParent)
-    , mrColor(rColor)
+    , mpColor(pColor)
     , mpComplexColor(pComplexColor)
 {
 }
@@ -304,7 +277,7 @@ ColorContext::ColorContext(ContextHandler2Helper const & 
rParent, Color& rColor,
         case A_TOKEN( sysClr ):
         case A_TOKEN( schemeClr ):
         case A_TOKEN( prstClr ):
-            return new ColorValueContext(*this, mrColor, mpComplexColor);
+            return new ColorValueContext(*this, mpColor, mpComplexColor);
     }
     return nullptr;
 }
@@ -328,7 +301,7 @@ ColorsContext::ColorsContext(ContextHandler2Helper const& 
rParent, std::vector<C
         case A_TOKEN(prstClr):
         {
             mrColors.emplace_back();
-            return new ColorValueContext(*this, mrColors.back(), nullptr);
+            return new ColorValueContext(*this, &mrColors.back(), nullptr);
         }
     }
     return nullptr;
diff --git a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx 
b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
index fe13f3b5d74d..71adf3dce612 100644
--- a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
+++ b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
@@ -111,7 +111,7 @@ 
DiagramQStylesFragmentHandler::DiagramQStylesFragmentHandler( XmlFilterBase& rFi
 {
     o_rStyle.mnThemedIdx = (nElement == A_TOKEN(fontRef)) ?
         rAttribs.getToken( XML_idx, XML_none ) : rAttribs.getInteger( XML_idx, 
0 );
-    return new ColorContext( *this, o_rStyle.maPhClr );
+    return new ColorContext(*this, &o_rStyle.maPhClr);
 }
 
 ::oox::core::ContextHandlerRef DiagramQStylesFragmentHandler::onCreateContext( 
sal_Int32 nElement,
diff --git a/oox/source/drawingml/effectpropertiescontext.cxx 
b/oox/source/drawingml/effectpropertiescontext.cxx
index ea949017cae2..9a468a6da0cc 100644
--- a/oox/source/drawingml/effectpropertiescontext.cxx
+++ b/oox/source/drawingml/effectpropertiescontext.cxx
@@ -105,7 +105,7 @@ ContextHandlerRef EffectPropertiesContext::onCreateContext( 
sal_Int32 nElement,
                 rEffect.mbRotateWithShape = rAttribs.getBool(XML_rotWithShape, 
true); // boolean, default "true"
                 pColor = &rEffect.maColor;
             }
-            return new ColorContext(*this, 
mrEffectProperties.m_Effects[nPos]->moColor, pColor);
+            return new ColorContext(*this, 
&mrEffectProperties.m_Effects[nPos]->moColor, pColor);
         }
         break;
         case A_TOKEN( innerShdw ):
@@ -126,7 +126,7 @@ ContextHandlerRef EffectPropertiesContext::onCreateContext( 
sal_Int32 nElement,
                 rEffect.mnDirection = rAttribs.getInteger(XML_dir, 0); // 
ST_PositiveFixedAngle, default 0
                 pColor = &rEffect.maColor;
             }
-            return new ColorContext(*this, 
mrEffectProperties.m_Effects[nPos]->moColor, pColor);
+            return new ColorContext(*this, 
&mrEffectProperties.m_Effects[nPos]->moColor, pColor);
         }
         break;
         case A_TOKEN( glow ):
@@ -143,7 +143,7 @@ ContextHandlerRef EffectPropertiesContext::onCreateContext( 
sal_Int32 nElement,
                 rEffect.mnRadius = rAttribs.getInteger(XML_rad, 0); 
//ST_PositiveCoordinate, default 0
                 pColor = &rEffect.maColor;
             }
-            return new ColorContext(*this, 
mrEffectProperties.maGlow.moGlowColor, pColor);
+            return new ColorContext(*this, 
&mrEffectProperties.maGlow.moGlowColor, pColor);
 
         }
         case A_TOKEN( softEdge ):
@@ -186,7 +186,7 @@ ContextHandlerRef EffectPropertiesContext::onCreateContext( 
sal_Int32 nElement,
 
                 pColor = &rEffect.maColor;
             }
-            return new ColorContext(*this, 
mrEffectProperties.m_Effects[nPos]->moColor, pColor);
+            return new ColorContext(*this, 
&mrEffectProperties.m_Effects[nPos]->moColor, pColor);
         }
         case A_TOKEN( blur ):
         {
@@ -202,7 +202,7 @@ ContextHandlerRef EffectPropertiesContext::onCreateContext( 
sal_Int32 nElement,
                 rEffect.mbGrow = rAttribs.getBool(XML_grow, true); // boolean, 
default true
                 pColor = &rEffect.maColor;
             }
-            return new ColorContext(*this, 
mrEffectProperties.m_Effects[nPos]->moColor, pColor);
+            return new ColorContext(*this, 
&mrEffectProperties.m_Effects[nPos]->moColor, pColor);
         }
         break;
     }
diff --git a/oox/source/drawingml/misccontexts.cxx 
b/oox/source/drawingml/misccontexts.cxx
index 0883596d2ca8..228ad2022b84 100644
--- a/oox/source/drawingml/misccontexts.cxx
+++ b/oox/source/drawingml/misccontexts.cxx
@@ -32,6 +32,7 @@
 #include <frozen/bits/defines.h>
 #include <frozen/bits/elsa_std.h>
 #include <frozen/unordered_map.h>
+#include <docmodel/color/ComplexColor.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -41,7 +42,7 @@ using ::oox::core::ContextHandlerRef;
 namespace oox::drawingml {
 
 SolidFillContext::SolidFillContext(ContextHandler2Helper const & rParent, 
FillProperties& rFillProps, model::SolidFill* pSolidFill)
-    : ColorContext(rParent, rFillProps.maFillColor, pSolidFill ? 
&pSolidFill->maColor : nullptr)
+    : ColorContext(rParent, &rFillProps.maFillColor, pSolidFill ? 
&pSolidFill->maColor : nullptr)
 {
 }
 
@@ -83,7 +84,7 @@ ContextHandlerRef GradientFillContext::onCreateContext(
                     pComplexColor = &rStop.maColor;
                 }
 
-                return new ColorContext(*this, aElement->second, 
pComplexColor);
+                return new ColorContext(*this, &aElement->second, 
pComplexColor);
             }
         break;
 
@@ -236,11 +237,11 @@ ContextHandlerRef PatternFillContext::onCreateContext(
         case A_TOKEN( bgClr ):
             if (mpPatternFill)
                 pComplexColor = &mpPatternFill->maBackgroundColor;
-            return new ColorContext(*this, mrPatternProps.maPattBgColor, 
pComplexColor);
+            return new ColorContext(*this, &mrPatternProps.maPattBgColor, 
pComplexColor);
         case A_TOKEN( fgClr ):
             if (mpPatternFill)
                 pComplexColor = &mpPatternFill->maForegroundColor;
-            return new ColorContext(*this, mrPatternProps.maPattFgColor, 
pComplexColor);
+            return new ColorContext(*this, &mrPatternProps.maPattFgColor, 
pComplexColor);
     }
     return nullptr;
 }
@@ -280,14 +281,14 @@ ContextHandlerRef ColorChangeContext::onCreateContext(
                 auto& rEffect = mpBlipFill->maBlipEffects.back();
                 pComplexColor = &rEffect.getColorFrom();
             }
-            return new ColorContext(*this, mrBlipProps.maColorChangeFrom, 
pComplexColor);
+            return new ColorContext(*this, &mrBlipProps.maColorChangeFrom, 
pComplexColor);
         case A_TOKEN(clrTo):
             if (mpBlipFill)
             {
                 auto& rEffect = mpBlipFill->maBlipEffects.back();
                 pComplexColor = &rEffect.getColorTo();
             }
-            return new ColorContext(*this, mrBlipProps.maColorChangeTo, 
pComplexColor);
+            return new ColorContext(*this, &mrBlipProps.maColorChangeTo, 
pComplexColor);
     }
     return nullptr;
 }
@@ -418,7 +419,7 @@ DuotoneContext::~DuotoneContext()
         sal_Int32 /*nElement*/, const AttributeList& /*rAttribs*/ )
 {
     if( mnColorIndex < 2 )
-        return new ColorValueContext(*this, 
mrBlipProps.maDuotoneColors[mnColorIndex++], nullptr);
+        return new ColorValueContext(*this, 
&mrBlipProps.maDuotoneColors[mnColorIndex++], nullptr);
     return nullptr;
 }
 
@@ -587,15 +588,18 @@ ContextHandlerRef 
FillPropertiesContext::createFillContext(
     return nullptr;
 }
 
-SimpleFillPropertiesContext::SimpleFillPropertiesContext( 
ContextHandler2Helper const & rParent, Color& rColor ) :
-    FillPropertiesContext( rParent, *this ),
-    mrColor( rColor )
+SimpleFillPropertiesContext::SimpleFillPropertiesContext(ContextHandler2Helper 
const & rParent, model::ComplexColor& rColor, Color *pOOXColor)
+    : FillPropertiesContext(rParent, *this)
+    , mrColor(rColor)
+    , mpOOXColor(pOOXColor)
 {
 }
 
 SimpleFillPropertiesContext::~SimpleFillPropertiesContext()
 {
-    mrColor = getBestSolidColor();
+    mrColor = 
getBestSolidColor().createComplexColor(getFilter().getGraphicHelper(), -1);
+    if (mpOOXColor)
+        *mpOOXColor = getBestSolidColor();
 }
 
 BlipExtensionContext::BlipExtensionContext(ContextHandler2Helper const & 
rParent, BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill)
diff --git a/oox/source/drawingml/scene3dcontext.cxx 
b/oox/source/drawingml/scene3dcontext.cxx
index 55f4550af3de..78252c998515 100644
--- a/oox/source/drawingml/scene3dcontext.cxx
+++ b/oox/source/drawingml/scene3dcontext.cxx
@@ -110,10 +110,10 @@ ContextHandlerRef 
SceneText3DPropertiesContext::onCreateContext( sal_Int32 aElem
     }
 
     case A_TOKEN( extrusionClr ):
-        return new ColorContext( *this, mr3DProperties.maExtrusionColor );
+        return new ColorContext( *this, &mr3DProperties.maExtrusionColor );
 
     case A_TOKEN( contourClr ):
-        return new ColorContext( *this, mr3DProperties.maContourColor );
+        return new ColorContext( *this, &mr3DProperties.maContourColor );
     }
     return nullptr;
 }
@@ -155,10 +155,10 @@ ContextHandlerRef 
Shape3DPropertiesContext::onCreateContext( sal_Int32 aElementT
         break;
     }
     case A_TOKEN( extrusionClr ):
-        return new ColorContext( *this, mr3DProperties.maExtrusionColor );
+        return new ColorContext( *this, &mr3DProperties.maExtrusionColor );
 
     case A_TOKEN( contourClr ):
-        return new ColorContext( *this, mr3DProperties.maContourColor );
+        return new ColorContext( *this, &mr3DProperties.maContourColor );
     }
     return nullptr;
 }
diff --git a/oox/source/drawingml/shapestylecontext.cxx 
b/oox/source/drawingml/shapestylecontext.cxx
index c8cec4b6e9d5..1abad008e341 100644
--- a/oox/source/drawingml/shapestylecontext.cxx
+++ b/oox/source/drawingml/shapestylecontext.cxx
@@ -57,7 +57,7 @@ ContextHandlerRef ShapeStyleContext::onCreateContext( 
sal_Int32 aElementToken, c
             // tx1 in such cases
             if( nToken == XML_fontRef && !rStyleRef.maPhClr.isUsed() )
                 rStyleRef.maPhClr.setSchemeClr(XML_tx1);
-            return new ColorContext( *this, rStyleRef.maPhClr );
+            return new ColorContext(*this, &rStyleRef.maPhClr);
         }
     }
     return nullptr;
diff --git a/oox/source/drawingml/table/tablebackgroundstylecontext.cxx 
b/oox/source/drawingml/table/tablebackgroundstylecontext.cxx
index 09952662fba2..4443f194b5e4 100644
--- a/oox/source/drawingml/table/tablebackgroundstylecontext.cxx
+++ b/oox/source/drawingml/table/tablebackgroundstylecontext.cxx
@@ -56,7 +56,7 @@ TableBackgroundStyleContext::onCreateContext( ::sal_Int32 
aElementToken, const A
             {
                 ShapeStyleRef& rStyleRef = 
mrTableStyle.getBackgroundFillStyleRef();
                 rStyleRef.mnThemedIdx = rAttribs.getInteger( XML_idx, 0 );
-                return new ColorContext( *this, rStyleRef.maPhClr );
+                return new ColorContext(*this, &rStyleRef.maPhClr);
             }
         // EG_ThemeableEffectStyle (choice)
         case A_TOKEN( effect ):     // CT_EffectProperties
diff --git a/oox/source/drawingml/table/tablecontext.cxx 
b/oox/source/drawingml/table/tablecontext.cxx
index c3bd979cfaf5..fd7707ff717b 100644
--- a/oox/source/drawingml/table/tablecontext.cxx
+++ b/oox/source/drawingml/table/tablecontext.cxx
@@ -60,7 +60,7 @@ TableContext::onCreateContext( ::sal_Int32 aElementToken, 
const AttributeList& r
         }
         break;
     case A_TOKEN(solidFill):
-        return new ColorContext(*this, mrTableProperties.getBgColor());
+        return new ColorContext(*this, &mrTableProperties.getBgColor());
     case A_TOKEN( tableStyle ):         // CT_TableStyle
         {
             std::shared_ptr< TableStyle >& rTableStyle = 
mrTableProperties.getTableStyle();
diff --git a/oox/source/drawingml/table/tablestylecellstylecontext.cxx 
b/oox/source/drawingml/table/tablestylecellstylecontext.cxx
index 57b314df68d2..20d68d14f933 100644
--- a/oox/source/drawingml/table/tablestylecellstylecontext.cxx
+++ b/oox/source/drawingml/table/tablestylecellstylecontext.cxx
@@ -79,7 +79,7 @@ TableStyleCellStyleContext::onCreateContext( ::sal_Int32 
aElementToken, const At
                 {
                     ShapeStyleRef& rLineStyleRef = 
mrTableStylePart.getStyleRefs()[ mnLineType ];
                     rLineStyleRef.mnThemedIdx = rAttribs.getInteger( XML_idx, 
0 );
-                    return new ColorContext( *this, rLineStyleRef.maPhClr );
+                    return new ColorContext(*this, &rLineStyleRef.maPhClr);
                 }
             }
             break;
@@ -95,7 +95,7 @@ TableStyleCellStyleContext::onCreateContext( ::sal_Int32 
aElementToken, const At
             {
                 ShapeStyleRef& rStyleRef = mrTableStylePart.getStyleRefs()[ 
XML_fillRef ];
                 rStyleRef.mnThemedIdx = rAttribs.getInteger( XML_idx, 0 );
-                return new ColorContext( *this, rStyleRef.maPhClr );
+                return new ColorContext(*this, &rStyleRef.maPhClr);
             }
         case A_TOKEN( cell3D ):     // CT_Cell3D
             break;
diff --git a/oox/source/drawingml/table/tablestyletextstylecontext.cxx 
b/oox/source/drawingml/table/tablestyletextstylecontext.cxx
index c4733cca5de3..21fb6828b52c 100644
--- a/oox/source/drawingml/table/tablestyletextstylecontext.cxx
+++ b/oox/source/drawingml/table/tablestyletextstylecontext.cxx
@@ -81,14 +81,14 @@ TableStyleTextStyleContext::onCreateContext( ::sal_Int32 
aElementToken, const At
             {
                 ShapeStyleRef& rFontStyle = mrTableStylePart.getStyleRefs()[ 
XML_fontRef ];
                 rFontStyle.mnThemedIdx = rAttribs.getToken( XML_idx, XML_none 
);
-                return new ColorContext( *this, rFontStyle.maPhClr );
+                return new ColorContext(*this, &rFontStyle.maPhClr);
             }
 
         case A_TOKEN( extLst ):     // CT_OfficeArtExtensionList
             break;
     }
 
-    return new ColorValueContext( *this, mrTableStylePart.getTextColor() );
+    return new ColorValueContext(*this, &mrTableStylePart.getTextColor());
 }
 
 }
diff --git a/oox/source/drawingml/textcharacterproperties.cxx 
b/oox/source/drawingml/textcharacterproperties.cxx
index a32512743085..28c0f8536cb0 100644
--- a/oox/source/drawingml/textcharacterproperties.cxx
+++ b/oox/source/drawingml/textcharacterproperties.cxx
@@ -54,6 +54,7 @@ void TextCharacterProperties::assignUsed( const 
TextCharacterProperties& rSource
     maComplexThemeFont.assignIfUsed( rSourceProps.maComplexThemeFont );
     maSymbolFont.assignIfUsed( rSourceProps.maSymbolFont );
     maHighlightColor.assignIfUsed( rSourceProps.maHighlightColor );
+    maHighlightOOXColor.assignIfUsed( rSourceProps.maHighlightOOXColor );
     maUnderlineColor.assignIfUsed( rSourceProps.maUnderlineColor );
     assignIfUsed( moLang, rSourceProps.moLang );
     assignIfUsed( moHeight, rSourceProps.moHeight );
@@ -214,9 +215,8 @@ void TextCharacterProperties::pushToPropMap( PropertyMap& 
rPropMap, const XmlFil
     if( moUnderline.has_value() && maUnderlineColor.isUsed() && 
!bUnderlineFillFollowText )
     {
         rPropMap.setProperty( PROP_CharUnderlineHasColor, true);
-        rPropMap.setProperty( PROP_CharUnderlineColor, 
maUnderlineColor.getColor( rFilter.getGraphicHelper() ));
-        model::ComplexColor aComplexColor = maUnderlineColor.getComplexColor();
-        rPropMap.setProperty( PROP_CharUnderlineComplexColor, 
model::color::createXComplexColor(aComplexColor));
+        rPropMap.setProperty( PROP_CharUnderlineColor, 
maUnderlineColor.getRGBColor());
+        rPropMap.setProperty( PROP_CharUnderlineComplexColor, 
model::color::createXComplexColor(maUnderlineColor));
     }
     else
     {
@@ -224,11 +224,10 @@ void TextCharacterProperties::pushToPropMap( PropertyMap& 
rPropMap, const XmlFil
         rPropMap.setProperty( PROP_CharUnderlineColor, sal_Int32(-1));
     }
 
-    if (maHighlightColor.isUsed() && maHighlightColor.getTransparency() != 100)
+    if (maHighlightColor.isUsed() && !maHighlightColor.isTransparent())
     {
-        rPropMap.setProperty(PROP_CharBackColor, maHighlightColor.getColor( 
rFilter.getGraphicHelper() ));
-        model::ComplexColor aComplexColor = maHighlightColor.getComplexColor();
-        rPropMap.setProperty(PROP_CharBackgroundComplexColor, 
model::color::createXComplexColor(aComplexColor));
+        rPropMap.setProperty(PROP_CharBackColor, maHighlightOOXColor.getColor( 
rFilter.getGraphicHelper() ));
+        rPropMap.setProperty(PROP_CharBackgroundComplexColor, 
model::color::createXComplexColor(maHighlightColor));
     }
     else
         rPropMap.setProperty( PROP_CharBackColor, sal_Int32(-1));
diff --git a/oox/source/drawingml/textcharacterpropertiescontext.cxx 
b/oox/source/drawingml/textcharacterpropertiescontext.cxx
index 711fa153b697..e1a4beb9f041 100644
--- a/oox/source/drawingml/textcharacterpropertiescontext.cxx
+++ b/oox/source/drawingml/textcharacterpropertiescontext.cxx
@@ -30,7 +30,7 @@
 #include <oox/token/namespaces.hxx>
 #include <oox/token/tokens.hxx>
 #include <sax/fastattribs.hxx>
-
+#include <oox/core/xmlfilterbase.hxx>
 #include <sal/log.hxx>
 
 using namespace ::oox::core;
@@ -133,9 +133,13 @@ ContextHandlerRef 
TextCharacterPropertiesContext::onCreateContext( sal_Int32 aEl
             return new EffectPropertiesContext(*this, 
mrTextCharacterProperties.getEffectProperties());
         break;
         case A_TOKEN( highlight ):  // CT_Color
-            return new ColorContext(*this, 
mrTextCharacterProperties.maHighlightColor);
+            return new ColorContext(*this,
+                    &mrTextCharacterProperties.maHighlightOOXColor,
+                    &mrTextCharacterProperties.maHighlightColor);
         case W_TOKEN( highlight ):
-            mrTextCharacterProperties.maHighlightColor = 
rAttribs.getHighlightColor(W_TOKEN(val));
+            mrTextCharacterProperties.maHighlightOOXColor = 
rAttribs.getHighlightColor(W_TOKEN(val));
+            mrTextCharacterProperties.maHighlightColor =
+                
mrTextCharacterProperties.maHighlightOOXColor.createComplexColor(getFilter().getGraphicHelper(),
 0);
             break;
         // EG_TextUnderlineLine
         case A_TOKEN( uLnTx ):      // CT_TextUnderlineLineFollowText
@@ -150,7 +154,7 @@ ContextHandlerRef 
TextCharacterPropertiesContext::onCreateContext( sal_Int32 aEl
             mrTextCharacterProperties.moUnderlineFillFollowText = true;
         break;
         case A_TOKEN( uFill ):      // 
CT_TextUnderlineFillGroupWrapper->EG_FillProperties (not supported)
-            return new SimpleFillPropertiesContext( *this, 
mrTextCharacterProperties.maUnderlineColor );
+            return new SimpleFillPropertiesContext( *this, 
mrTextCharacterProperties.maUnderlineColor, nullptr);
 
         // CT_FontCollection
         case A_TOKEN( latin ):      // CT_TextFont
@@ -238,7 +242,7 @@ ContextHandlerRef 
TextCharacterPropertiesContext::onCreateContext( sal_Int32 aEl
             {
                 oox::drawingml::Color theColor;
                 theColor.setSrgbClr(colorAttrib.value());
-                mrTextCharacterProperties.maUnderlineColor = 
std::move(theColor);
+                mrTextCharacterProperties.maUnderlineColor = 
theColor.getComplexColor();
             }
             break;
         }
diff --git a/oox/source/drawingml/textparagraphpropertiescontext.cxx 
b/oox/source/drawingml/textparagraphpropertiescontext.cxx
index 3cae4f89e6a5..3f0a47488784 100644
--- a/oox/source/drawingml/textparagraphpropertiescontext.cxx
+++ b/oox/source/drawingml/textparagraphpropertiescontext.cxx
@@ -265,7 +265,7 @@ ContextHandlerRef 
TextParagraphPropertiesContext::onCreateContext( sal_Int32 aEl
             mrBulletList.mbBulletColorFollowText <<= true;
             break;
         case A_TOKEN( buClr ):          // CT_Color
-            return new ColorContext( *this, *mrBulletList.maBulletColorPtr );
+            return new ColorContext(*this, 
mrBulletList.maBulletColorPtr.get());
         // EG_TextBulletSize
         case A_TOKEN( buSzTx ):         // CT_TextBulletSizeFollowText
             mrBulletList.mbBulletSizeFollowText <<= true;
diff --git a/oox/source/export/ThemeExport.cxx 
b/oox/source/export/ThemeExport.cxx
index 8f76e49af3f8..bdd79016aac7 100644
--- a/oox/source/export/ThemeExport.cxx
+++ b/oox/source/export/ThemeExport.cxx
@@ -322,6 +322,9 @@ void ThemeExport::writeComplexColor(model::ComplexColor 
const& rComplexColor)
         case model::ColorType::Placeholder:
             writeColorPlaceholder(rComplexColor);
             break;
+        case model::ColorType::Finalized:
+            assert(false);
+            break;
     }
 }
 
diff --git a/oox/source/ppt/animvariantcontext.cxx 
b/oox/source/ppt/animvariantcontext.cxx
index ed1d805a1642..52417dd8921d 100644
--- a/oox/source/ppt/animvariantcontext.cxx
+++ b/oox/source/ppt/animvariantcontext.cxx
@@ -62,7 +62,7 @@ namespace oox::ppt {
             return this;
         }
         case PPT_TOKEN( clrVal ):
-            return new ::oox::drawingml::ColorContext( *this, maColor );
+            return new ::oox::drawingml::ColorContext(*this, &maColor);
             // we'll defer setting the Any until the end.
         case PPT_TOKEN( fltVal ):
         {
diff --git a/oox/source/ppt/slidefragmenthandler.cxx 
b/oox/source/ppt/slidefragmenthandler.cxx
index ee87d752a65f..7a708553fcd5 100644
--- a/oox/source/ppt/slidefragmenthandler.cxx
+++ b/oox/source/ppt/slidefragmenthandler.cxx
@@ -182,7 +182,7 @@ SlideFragmentHandler::~SlideFragmentHandler()
                 ? std::make_shared<FillProperties>( *pFillProperties )
                 : std::make_shared<FillProperties>();
             mpSlidePersistPtr->setBackgroundProperties( pFillPropertiesPtr );
-            ContextHandlerRef ret = new ColorContext( *this, 
mpSlidePersistPtr->getBackgroundColor() );
+            ContextHandlerRef ret = new ColorContext(*this, 
&mpSlidePersistPtr->getBackgroundColor());
             return ret;
         }
         break;
diff --git a/oox/source/ppt/timenodelistcontext.cxx 
b/oox/source/ppt/timenodelistcontext.cxx
index 70c75ffd17cd..b36e479373c9 100644
--- a/oox/source/ppt/timenodelistcontext.cxx
+++ b/oox/source/ppt/timenodelistcontext.cxx
@@ -503,10 +503,10 @@ namespace oox::ppt {
                     return new CommonBehaviorContext ( *this, mpNode );
                 case PPT_TOKEN( to ):
                     // CT_Color
-                    return new ColorContext( *this, maToClr );
+                    return new ColorContext(*this, &maToClr);
                 case PPT_TOKEN( from ):
                     // CT_Color
-                    return new ColorContext( *this, maFromClr );
+                    return new ColorContext(*this, &maFromClr);
 
                 default:
                     break;

Reply via email to