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 ): {