include/docmodel/theme/FormatScheme.hxx  |   46 +++++++++++++++
 include/oox/drawingml/drawingmltypes.hxx |    4 +
 oox/inc/drawingml/misccontexts.hxx       |    8 +-
 oox/source/drawingml/drawingmltypes.cxx  |    8 ++
 oox/source/drawingml/misccontexts.cxx    |   93 ++++++++++++++++++++++++-------
 5 files changed, 135 insertions(+), 24 deletions(-)

New commits:
commit 0d18262789fbe95eafe32bd775a9827ed99685ef
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Fri Feb 24 00:48:55 2023 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Thu Mar 23 02:28:08 2023 +0000

    oox: import gradient fill to model::FormatScheme
    
    Change-Id: I90bc7cf4239f08efbc7239928c34ccdbec20cb2c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147575
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/include/docmodel/theme/FormatScheme.hxx 
b/include/docmodel/theme/FormatScheme.hxx
index a256532791d9..39fa5d36ae0b 100644
--- a/include/docmodel/theme/FormatScheme.hxx
+++ b/include/docmodel/theme/FormatScheme.hxx
@@ -159,6 +159,52 @@ public:
     }
 };
 
+class DOCMODEL_DLLPUBLIC GradientStop
+{
+public:
+    double mfPosition = 0.0; // 0.0 - 1.0
+    ColorDefinition maColor;
+};
+
+enum class GradientType
+{
+    Undefined,
+    Linear,
+    Circle,
+    Rectangle,
+    Shape,
+};
+
+struct DOCMODEL_DLLPUBLIC LinearGradientProperties
+{
+    sal_Int32 mnAngle = 0;
+    bool mbScaled = false;
+};
+
+struct DOCMODEL_DLLPUBLIC RelativeRectangle
+{
+    sal_Int32 mnLeft = 0;
+    sal_Int32 mnTop = 0;
+    sal_Int32 mnRight = 0;
+    sal_Int32 mnBottom = 0;
+};
+
+class DOCMODEL_DLLPUBLIC GradientFill : public Fill
+{
+public:
+    bool mbRotateWithShape = false;
+    GradientType meGradientType = GradientType::Undefined;
+    std::vector<GradientStop> maGradientStops;
+    LinearGradientProperties maLinearGradient;
+    RelativeRectangle maFillToRectangle;
+    RelativeRectangle maTileRectangle;
+
+    GradientFill()
+        : Fill(FillType::Gradient)
+    {
+    }
+};
+
 // Format Scheme
 
 class DOCMODEL_DLLPUBLIC FillStyle
diff --git a/include/oox/drawingml/drawingmltypes.hxx 
b/include/oox/drawingml/drawingmltypes.hxx
index 5fe86d56439e..8dd5dee727d4 100644
--- a/include/oox/drawingml/drawingmltypes.hxx
+++ b/include/oox/drawingml/drawingmltypes.hxx
@@ -31,6 +31,7 @@
 #include <com/sun/star/style/TabAlign.hpp>
 #include <com/sun/star/uno/Reference.hxx>
 #include <o3tl/unit_conversion.hxx>
+#include <docmodel/theme/FormatScheme.hxx>
 #include <oox/dllapi.h>
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
@@ -100,6 +101,9 @@ css::awt::Size GetSize2D( const css::uno::Reference< 
css::xml::sax::XFastAttribu
 /** converts the attributes from a CT_RelativeRect to an IntegerRectangle2D */
 css::geometry::IntegerRectangle2D GetRelativeRect( const css::uno::Reference< 
css::xml::sax::XFastAttributeList >& xAttributes );
 
+void fillRelativeRectangle(model::RelativeRectangle& rRelativeRectangle,
+                           const 
css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttributes);
+
 /** converts EMUs into 1/100th mmm */
 sal_Int32 GetCoordinate( sal_Int32 nValue );
 
diff --git a/oox/inc/drawingml/misccontexts.hxx 
b/oox/inc/drawingml/misccontexts.hxx
index e2e255d10b64..6bbaa74efcf2 100644
--- a/oox/inc/drawingml/misccontexts.hxx
+++ b/oox/inc/drawingml/misccontexts.hxx
@@ -42,10 +42,9 @@ public:
 class GradientFillContext final : public ::oox::core::ContextHandler2
 {
 public:
-    explicit            GradientFillContext(
-                            ::oox::core::ContextHandler2Helper const & rParent,
-                            const ::oox::AttributeList& rAttribs,
-                            GradientFillProperties& rGradientProps );
+    explicit GradientFillContext(::oox::core::ContextHandler2Helper const & 
rParent,
+        const ::oox::AttributeList& rAttribs, GradientFillProperties& 
rGradientProps,
+        model::GradientFill* pGradientFill);
 
     virtual ::oox::core::ContextHandlerRef
                         onCreateContext(
@@ -53,6 +52,7 @@ public:
                             const ::oox::AttributeList& rAttribs ) override;
 
 private:
+    model::GradientFill* mpGradientFill;
     GradientFillProperties& mrGradientProps;
 };
 
diff --git a/oox/source/drawingml/drawingmltypes.cxx 
b/oox/source/drawingml/drawingmltypes.cxx
index fc2f28d902b7..d0bf1bf2c892 100644
--- a/oox/source/drawingml/drawingmltypes.cxx
+++ b/oox/source/drawingml/drawingmltypes.cxx
@@ -400,6 +400,14 @@ IntegerRectangle2D GetRelativeRect( const Reference< 
XFastAttributeList >& xAttr
     return r;
 }
 
+void fillRelativeRectangle(model::RelativeRectangle& rRelativeRectangle, const 
Reference<XFastAttributeList>& xAttribs)
+{
+    rRelativeRectangle.mnLeft = 
GetST_Percentage(xAttribs->getOptionalValue(XML_l));
+    rRelativeRectangle.mnTop = 
GetST_Percentage(xAttribs->getOptionalValue(XML_t));
+    rRelativeRectangle.mnRight = 
GetST_Percentage(xAttribs->getOptionalValue(XML_r));
+    rRelativeRectangle.mnBottom = 
GetST_Percentage(xAttribs->getOptionalValue(XML_b));
+}
+
 /** converts the attributes from a CT_Size2D into an awt Size with 1/100thmm */
 awt::Size GetSize2D( const Reference< XFastAttributeList >& xAttribs )
 {
diff --git a/oox/source/drawingml/misccontexts.cxx 
b/oox/source/drawingml/misccontexts.cxx
index 9a5ff0e75572..e72e6ea40d74 100644
--- a/oox/source/drawingml/misccontexts.cxx
+++ b/oox/source/drawingml/misccontexts.cxx
@@ -44,13 +44,17 @@ SolidFillContext::SolidFillContext(ContextHandler2Helper 
const & rParent, FillPr
 SolidFillContext::~SolidFillContext()
 {}
 
-GradientFillContext::GradientFillContext( ContextHandler2Helper const & 
rParent,
-        const AttributeList& rAttribs, GradientFillProperties& rGradientProps 
) :
-    ContextHandler2( rParent ),
-    mrGradientProps( rGradientProps )
+GradientFillContext::GradientFillContext(ContextHandler2Helper const & rParent,
+        const AttributeList& rAttribs, GradientFillProperties& rGradientProps, 
model::GradientFill* pGradientFill)
+    : ContextHandler2(rParent)
+    , mpGradientFill(pGradientFill)
+    , mrGradientProps(rGradientProps)
 {
+    auto oRotateWithShape = rAttribs.getBool(XML_rotWithShape);
     mrGradientProps.moShadeFlip = rAttribs.getToken( XML_flip );
-    mrGradientProps.moRotateWithShape = rAttribs.getBool( XML_rotWithShape );
+    mrGradientProps.moRotateWithShape = oRotateWithShape;
+    if (mpGradientFill && oRotateWithShape)
+        mpGradientFill->mbRotateWithShape = *oRotateWithShape;
 }
 
 ContextHandlerRef GradientFillContext::onCreateContext(
@@ -62,30 +66,73 @@ ContextHandlerRef GradientFillContext::onCreateContext(
             return this;    // for gs elements
 
         case A_TOKEN( gs ):
-            if( rAttribs.hasAttribute( XML_pos ) )
+            if (rAttribs.hasAttribute(XML_pos))
             {
-                double fPosition = getLimitedValue< double >( 
rAttribs.getDouble( XML_pos, 0.0 ) / 100000.0, 0.0, 1.0 );
-                auto aElement = mrGradientProps.maGradientStops.emplace( 
fPosition, Color() );
-                return new ColorContext( *this, aElement->second );
+                double fPosition = 
getLimitedValue<double>(rAttribs.getDouble(XML_pos, 0.0) / 100000.0, 0.0, 1.0);
+                auto aElement = 
mrGradientProps.maGradientStops.emplace(fPosition, Color());
+
+                model::ColorDefinition* pColorDefinition = nullptr;
+                if (mpGradientFill)
+                {
+                    model::GradientStop& rStop = 
mpGradientFill->maGradientStops.emplace_back();
+                    rStop.mfPosition = fPosition;
+                    pColorDefinition = &rStop.maColor;
+                }
+
+                return new ColorContext(*this, aElement->second, 
pColorDefinition);
             }
         break;
 
         case A_TOKEN( lin ):
-            mrGradientProps.moShadeAngle = rAttribs.getInteger( XML_ang );
-            mrGradientProps.moShadeScaled = rAttribs.getBool( XML_scaled );
+        {
+            mrGradientProps.moShadeAngle = rAttribs.getInteger(XML_ang);
+            mrGradientProps.moShadeScaled = rAttribs.getBool(XML_scaled);
+
+            if (mpGradientFill)
+            {
+                mpGradientFill->meGradientType = model::GradientType::Linear;
+                mpGradientFill->maLinearGradient.mnAngle = 
rAttribs.getInteger(XML_ang, 0);
+                mpGradientFill->maLinearGradient.mbScaled = 
rAttribs.getBool(XML_scaled, false);
+            }
+        }
         break;
 
         case A_TOKEN( path ):
+        {
             // always set a path type, this disables linear gradient in 
conversion
-            mrGradientProps.moGradientPath = rAttribs.getToken( XML_path, 
XML_rect );
+            sal_Int32 nToken = rAttribs.getToken(XML_path, XML_rect);
+            mrGradientProps.moGradientPath = nToken;
+            if (mpGradientFill)
+            {
+                switch (nToken)
+                {
+                    case XML_rect:
+                        mpGradientFill->meGradientType = 
model::GradientType::Rectangle;
+                        break;
+                    case XML_circle:
+                        mpGradientFill->meGradientType = 
model::GradientType::Circle;
+                        break;
+                    case XML_shape:
+                        mpGradientFill->meGradientType = 
model::GradientType::Shape;
+                        break;
+                    default:
+                        break;
+                }
+            }
             return this;    // for fillToRect element
-
+        }
         case A_TOKEN( fillToRect ):
+        {
             mrGradientProps.moFillToRect = GetRelativeRect( 
rAttribs.getFastAttributeList() );
+            if (mpGradientFill)
+                fillRelativeRectangle(mpGradientFill->maFillToRectangle, 
rAttribs.getFastAttributeList());
+        }
         break;
 
         case A_TOKEN( tileRect ):
-            mrGradientProps.moTileRect = GetRelativeRect( 
rAttribs.getFastAttributeList() );
+            mrGradientProps.moTileRect = 
GetRelativeRect(rAttribs.getFastAttributeList());
+            if (mpGradientFill)
+                fillRelativeRectangle(mpGradientFill->maTileRectangle, 
rAttribs.getFastAttributeList());
         break;
     }
     return nullptr;
@@ -105,9 +152,9 @@ ContextHandlerRef PatternFillContext::onCreateContext(
     switch( nElement )
     {
         case A_TOKEN( bgClr ):
-            return new ColorContext( *this, mrPatternProps.maPattBgColor );
+            return new ColorContext(*this, mrPatternProps.maPattBgColor, 
nullptr);
         case A_TOKEN( fgClr ):
-            return new ColorContext( *this, mrPatternProps.maPattFgColor );
+            return new ColorContext(*this, mrPatternProps.maPattFgColor, 
nullptr);
     }
     return nullptr;
 }
@@ -134,9 +181,9 @@ ContextHandlerRef ColorChangeContext::onCreateContext(
     switch( nElement )
     {
         case A_TOKEN( clrFrom ):
-            return new ColorContext( *this, mrBlipProps.maColorChangeFrom );
+            return new ColorContext(*this, mrBlipProps.maColorChangeFrom, 
nullptr);
         case A_TOKEN( clrTo ):
-            return new ColorContext( *this, mrBlipProps.maColorChangeTo );
+            return new ColorContext(*this, mrBlipProps.maColorChangeTo, 
nullptr);
     }
     return nullptr;
 }
@@ -220,7 +267,7 @@ DuotoneContext::~DuotoneContext()
         sal_Int32 /*nElement*/, const AttributeList& /*rAttribs*/ )
 {
     if( mnColorIndex < 2 )
-        return new ColorValueContext( *this, 
mrBlipProps.maDuotoneColors[mnColorIndex++] );
+        return new ColorValueContext(*this, 
mrBlipProps.maDuotoneColors[mnColorIndex++], nullptr);
     return nullptr;
 }
 
@@ -307,7 +354,13 @@ ContextHandlerRef FillPropertiesContext::createFillContext(
         case A_TOKEN( gradFill ):
         {
             rFillProps.moFillType = getBaseToken(nElement);
-            return new GradientFillContext(rParent, rAttribs, 
rFillProps.maGradientProps);
+            model::GradientFill* pGradientFill = nullptr;
+            if (pFillStyle)
+            {
+                pFillStyle->mpFill = std::make_unique<model::GradientFill>();
+                pGradientFill = 
static_cast<model::GradientFill*>(pFillStyle->mpFill.get());
+            }
+            return new GradientFillContext(rParent, rAttribs, 
rFillProps.maGradientProps, pGradientFill);
         }
         case A_TOKEN( pattFill ):
         {

Reply via email to