include/docmodel/theme/FormatScheme.hxx | 67 +++++++ oox/inc/drawingml/misccontexts.hxx | 25 +- oox/source/drawingml/graphicshapecontext.cxx | 2 oox/source/drawingml/misccontexts.cxx | 144 +++++++++++++--- oox/source/drawingml/textparagraphpropertiescontext.cxx | 2 5 files changed, 201 insertions(+), 39 deletions(-)
New commits: commit 0ffa50031eb33500a3530ece76ea32d15864f345 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Tue Feb 28 18:09:46 2023 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Wed Apr 12 06:01:53 2023 +0200 oox: add model::BlipFilll and import blip (graphic) fill elements Change-Id: I610b732b1fd4eebcfcc55acb6f04a8acf84f92b7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147954 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 fea08ee50d1e..cd3c5491a62a 100644 --- a/include/docmodel/theme/FormatScheme.hxx +++ b/include/docmodel/theme/FormatScheme.hxx @@ -13,6 +13,7 @@ #include <docmodel/dllapi.h> #include <tools/color.hxx> #include <docmodel/theme/ThemeColor.hxx> +#include <com/sun/star/graphic/XGraphic.hpp> namespace model { @@ -277,6 +278,72 @@ public: } }; +enum class BitmapMode +{ + Unused, + Tile, + Stretch, +}; + +enum class FlipMode +{ + None, + X, + Y, + XY +}; + +enum class RectangleAlignment +{ + TopLeft, + Top, + TopRight, + Left, + Center, + Right, + BottomLeft, + Bottom, + BottomRight +}; + +enum class ColorEffectType +{ + None, + BiLevel, + Grayscale, + ColorChange +}; + +class DOCMODEL_DLLPUBLIC BlipFill : public Fill +{ +public: + bool mbRotateWithShape = false; + RelativeRectangle maClipRectangle; + RelativeRectangle maFillRectangle; + BitmapMode meMode = BitmapMode::Unused; + + sal_Int32 mnTileOffsetX = 0; + sal_Int32 mnTileOffsetY = 0; + sal_Int32 mnTileScaleX = 0; + sal_Int32 mnTileScaleY = 0; + FlipMode meTileFlipMode = FlipMode::None; + RectangleAlignment meTileAlignment = RectangleAlignment::TopLeft; + + css::uno::Reference<css::graphic::XGraphic> mxGraphic; + + ColorEffectType meColorEffectType = ColorEffectType::None; + + sal_Int32 mnBiLevelThreshold = 0; + ColorDefinition maColorFrom; + ColorDefinition maColorTo; + bool mbUseAlpha = false; + + BlipFill() + : Fill(FillType::Blip) + { + } +}; + // Format Scheme class DOCMODEL_DLLPUBLIC FillStyle diff --git a/oox/inc/drawingml/misccontexts.hxx b/oox/inc/drawingml/misccontexts.hxx index 10977df87d99..c79816282ae7 100644 --- a/oox/inc/drawingml/misccontexts.hxx +++ b/oox/inc/drawingml/misccontexts.hxx @@ -141,11 +141,9 @@ private: class ColorChangeContext final : public ::oox::core::ContextHandler2 { public: - explicit ColorChangeContext( - ::oox::core::ContextHandler2Helper const & rParent, - const ::oox::AttributeList& rAttribs, - BlipFillProperties& rBlipProps ); - virtual ~ColorChangeContext() override; + explicit ColorChangeContext(::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& rAttribs, + BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill); + virtual ~ColorChangeContext() override; virtual ::oox::core::ContextHandlerRef onCreateContext( @@ -153,8 +151,9 @@ public: const ::oox::AttributeList& rAttribs ) override; private: + model::BlipFill* mpBlipFill; BlipFillProperties& mrBlipProps; - bool mbUseAlpha; + bool mbUseAlpha; }; /** Context handler that imports the a:blip element containing the fill bitmap @@ -162,10 +161,8 @@ private: class BlipContext final : public ::oox::core::ContextHandler2 { public: - explicit BlipContext( - ::oox::core::ContextHandler2Helper const & rParent, - const ::oox::AttributeList& rAttribs, - BlipFillProperties& rBlipProps ); + explicit BlipContext(::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& rAttribs, + BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill); virtual ::oox::core::ContextHandlerRef onCreateContext( @@ -173,6 +170,7 @@ public: const ::oox::AttributeList& rAttribs ) override; private: + model::BlipFill* mpBlipFill; BlipFillProperties& mrBlipProps; }; @@ -180,10 +178,8 @@ private: class BlipFillContext final : public ::oox::core::ContextHandler2 { public: - explicit BlipFillContext( - ::oox::core::ContextHandler2Helper const & rParent, - const ::oox::AttributeList& rAttribs, - BlipFillProperties& rBlipProps ); + explicit BlipFillContext(::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& rAttribs, + BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill); virtual ::oox::core::ContextHandlerRef onCreateContext( @@ -191,6 +187,7 @@ public: const ::oox::AttributeList& rAttribs ) override; private: + model::BlipFill* mpBlipFill; BlipFillProperties& mrBlipProps; }; diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx index 0f96d0a92d63..4fb6af74e131 100644 --- a/oox/source/drawingml/graphicshapecontext.cxx +++ b/oox/source/drawingml/graphicshapecontext.cxx @@ -80,7 +80,7 @@ ContextHandlerRef GraphicShapeContext::onCreateContext( sal_Int32 aElementToken, case XML_xfrm: return new Transform2DContext( *this, rAttribs, *mpShapePtr ); case XML_blipFill: - return new BlipFillContext( *this, rAttribs, mpShapePtr->getGraphicProperties().maBlipProps ); + return new BlipFillContext(*this, rAttribs, mpShapePtr->getGraphicProperties().maBlipProps, nullptr); case XML_wavAudioFile: { OUString const path(getEmbeddedWAVAudioFile(getRelations(), rAttribs)); diff --git a/oox/source/drawingml/misccontexts.cxx b/oox/source/drawingml/misccontexts.cxx index 20cb60e953de..3005974bdf37 100644 --- a/oox/source/drawingml/misccontexts.cxx +++ b/oox/source/drawingml/misccontexts.cxx @@ -243,13 +243,19 @@ ContextHandlerRef PatternFillContext::onCreateContext( } ColorChangeContext::ColorChangeContext( ContextHandler2Helper const & rParent, - const AttributeList& rAttribs, BlipFillProperties& rBlipProps ) : - ContextHandler2( rParent ), - mrBlipProps( rBlipProps ) + const AttributeList& rAttribs, BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill) + : ContextHandler2(rParent) + , mpBlipFill(pBlipFill) + , mrBlipProps(rBlipProps) { mrBlipProps.maColorChangeFrom.setUnused(); mrBlipProps.maColorChangeTo.setUnused(); mbUseAlpha = rAttribs.getBool( XML_useA, true ); + if (mpBlipFill) + { + mpBlipFill->meColorEffectType = model::ColorEffectType::ColorChange; + mpBlipFill->mbUseAlpha = mbUseAlpha; + } } ColorChangeContext::~ColorChangeContext() @@ -261,27 +267,38 @@ ColorChangeContext::~ColorChangeContext() ContextHandlerRef ColorChangeContext::onCreateContext( sal_Int32 nElement, const AttributeList& ) { - switch( nElement ) + model::ColorDefinition* pColorDefinition = nullptr; + switch (nElement) { - case A_TOKEN( clrFrom ): - return new ColorContext(*this, mrBlipProps.maColorChangeFrom, nullptr); - case A_TOKEN( clrTo ): - return new ColorContext(*this, mrBlipProps.maColorChangeTo, nullptr); + case A_TOKEN(clrFrom): + if (mpBlipFill) + pColorDefinition = &mpBlipFill->maColorFrom; + return new ColorContext(*this, mrBlipProps.maColorChangeFrom, pColorDefinition); + case A_TOKEN(clrTo): + if (mpBlipFill) + pColorDefinition = &mpBlipFill->maColorTo; + return new ColorContext(*this, mrBlipProps.maColorChangeTo, pColorDefinition); } return nullptr; } -BlipContext::BlipContext( ContextHandler2Helper const & rParent, - const AttributeList& rAttribs, BlipFillProperties& rBlipProps ) : - ContextHandler2( rParent ), - mrBlipProps( rBlipProps ) +BlipContext::BlipContext(ContextHandler2Helper const & rParent, const AttributeList& rAttribs, + BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill) + : ContextHandler2(rParent) + , mpBlipFill(pBlipFill) + , mrBlipProps(rBlipProps) { if( rAttribs.hasAttribute( R_TOKEN( embed ) ) ) { // internal picture URL OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getStringDefaulted( R_TOKEN( embed )) ); if (!aFragmentPath.isEmpty()) - mrBlipProps.mxFillGraphic = getFilter().getGraphicHelper().importEmbeddedGraphic( aFragmentPath ); + { + auto xGraphic = getFilter().getGraphicHelper().importEmbeddedGraphic(aFragmentPath); + mrBlipProps.mxFillGraphic = xGraphic; + if (mpBlipFill) + mpBlipFill->mxGraphic = xGraphic; + } } else if( rAttribs.hasAttribute( R_TOKEN( link ) ) ) { @@ -294,7 +311,10 @@ BlipContext::BlipContext( ContextHandler2Helper const & rParent, OUString aTargetLink = getFilter().getAbsoluteUrl( getRelations().getExternalTargetFromRelId( aRelId ) ); GraphicExternalLink aLink(aTargetLink); Graphic aGraphic(aLink); - mrBlipProps.mxFillGraphic = aGraphic.GetXGraphic(); + auto xGraphic = aGraphic.GetXGraphic(); + mrBlipProps.mxFillGraphic = xGraphic; + if (mpBlipFill) + mpBlipFill->mxGraphic = xGraphic; } } @@ -304,17 +324,32 @@ ContextHandlerRef BlipContext::onCreateContext( switch( nElement ) { case A_TOKEN( biLevel ): + { mrBlipProps.moBiLevelThreshold = rAttribs.getInteger( XML_thresh ); mrBlipProps.moColorEffect = getBaseToken(nElement); - break; + if (mpBlipFill) + { + mpBlipFill->meColorEffectType = model::ColorEffectType::BiLevel; + mpBlipFill->mnBiLevelThreshold = rAttribs.getInteger(XML_thresh, 0); + } + } + break; case A_TOKEN( grayscl ): + { mrBlipProps.moColorEffect = getBaseToken( nElement ); + if (mpBlipFill) + { + mpBlipFill->meColorEffectType = model::ColorEffectType::Grayscale; + } + } break; case A_TOKEN( clrChange ): - return new ColorChangeContext( *this, rAttribs, mrBlipProps ); - + { + return new ColorChangeContext(*this, rAttribs, mrBlipProps, mpBlipFill); + } + break; case A_TOKEN( duotone ): return new DuotoneContext( *this, mrBlipProps ); @@ -322,11 +357,15 @@ ContextHandlerRef BlipContext::onCreateContext( return new BlipExtensionContext( *this, mrBlipProps ); case A_TOKEN( lum ): + { mrBlipProps.moBrightness = rAttribs.getInteger( XML_bright ); mrBlipProps.moContrast = rAttribs.getInteger( XML_contrast ); + } break; case A_TOKEN( alphaModFix ): + { mrBlipProps.moAlphaModFix = rAttribs.getInteger(XML_amt); + } break; } return nullptr; @@ -354,12 +393,15 @@ DuotoneContext::~DuotoneContext() return nullptr; } -BlipFillContext::BlipFillContext( ContextHandler2Helper const & rParent, - const AttributeList& rAttribs, BlipFillProperties& rBlipProps ) : - ContextHandler2( rParent ), - mrBlipProps( rBlipProps ) +BlipFillContext::BlipFillContext(ContextHandler2Helper const & rParent, const AttributeList& rAttribs, + BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill) + : ContextHandler2( rParent ) + , mpBlipFill(pBlipFill) + , mrBlipProps(rBlipProps) { mrBlipProps.moRotateWithShape = rAttribs.getBool( XML_rotWithShape ); + if (mpBlipFill) + mpBlipFill->mbRotateWithShape = rAttribs.getBool(XML_rotWithShape, false); } ContextHandlerRef BlipFillContext::onCreateContext( @@ -368,13 +410,19 @@ ContextHandlerRef BlipFillContext::onCreateContext( switch( nElement ) { case A_TOKEN( blip ): - return new BlipContext( *this, rAttribs, mrBlipProps ); + return new BlipContext(*this, rAttribs, mrBlipProps, mpBlipFill); case A_TOKEN( srcRect ): + { mrBlipProps.moClipRect = GetRelativeRect( rAttribs.getFastAttributeList() ); + + if (mpBlipFill) + fillRelativeRectangle(mpBlipFill->maClipRectangle, rAttribs.getFastAttributeList()); + } break; case A_TOKEN( tile ): + { mrBlipProps.moBitmapMode = getBaseToken( nElement ); mrBlipProps.moTileOffsetX = rAttribs.getInteger( XML_tx ); mrBlipProps.moTileOffsetY = rAttribs.getInteger( XML_ty ); @@ -382,14 +430,58 @@ ContextHandlerRef BlipFillContext::onCreateContext( mrBlipProps.moTileScaleY = rAttribs.getInteger( XML_sy ); mrBlipProps.moTileAlign = rAttribs.getToken( XML_algn ); mrBlipProps.moTileFlip = rAttribs.getToken( XML_flip ); + + if (mpBlipFill) + { + mpBlipFill->meMode = model::BitmapMode::Tile; + mpBlipFill->mnTileOffsetX = rAttribs.getInteger(XML_tx, 0); + mpBlipFill->mnTileOffsetY = rAttribs.getInteger(XML_ty, 0); + mpBlipFill->mnTileScaleX = rAttribs.getInteger(XML_sx, 0); + mpBlipFill->mnTileScaleY = rAttribs.getInteger(XML_sy, 0); + + switch (rAttribs.getToken(XML_flip, XML_none)) + { + case XML_x: mpBlipFill->meTileFlipMode = model::FlipMode::X; break; + case XML_y: mpBlipFill->meTileFlipMode = model::FlipMode::Y; break; + case XML_xy: mpBlipFill->meTileFlipMode = model::FlipMode::XY; break; + default: + case XML_none: mpBlipFill->meTileFlipMode = model::FlipMode::None; break; + } + switch (rAttribs.getToken(XML_algn, XML_tl)) + { + default: + case XML_tl: mpBlipFill->meTileAlignment = model::RectangleAlignment::TopLeft; break; + case XML_t: mpBlipFill->meTileAlignment = model::RectangleAlignment::Top; break; + case XML_tr: mpBlipFill->meTileAlignment = model::RectangleAlignment::TopRight; break; + case XML_l: mpBlipFill->meTileAlignment = model::RectangleAlignment::Left; break; + case XML_ctr: mpBlipFill->meTileAlignment = model::RectangleAlignment::Center; break; + case XML_r: mpBlipFill->meTileAlignment = model::RectangleAlignment::Right; break; + case XML_bl: mpBlipFill->meTileAlignment = model::RectangleAlignment::BottomLeft; break; + case XML_b: mpBlipFill->meTileAlignment = model::RectangleAlignment::Bottom; break; + case XML_br: mpBlipFill->meTileAlignment = model::RectangleAlignment::BottomRight; break; + } + } + } break; case A_TOKEN( stretch ): + { mrBlipProps.moBitmapMode = getBaseToken( nElement ); + if (mpBlipFill) + { + mpBlipFill->meMode = model::BitmapMode::Stretch; + } return this; // for fillRect element + } + break; case A_TOKEN( fillRect ): + { mrBlipProps.moFillRect = GetRelativeRect( rAttribs.getFastAttributeList() ); + + if (mpBlipFill) + fillRelativeRectangle(mpBlipFill->maFillRectangle, rAttribs.getFastAttributeList()); + } break; } return nullptr; @@ -460,7 +552,13 @@ ContextHandlerRef FillPropertiesContext::createFillContext( case A_TOKEN( blipFill ): { rFillProps.moFillType = getBaseToken( nElement ); - return new BlipFillContext( rParent, rAttribs, rFillProps.maBlipProps ); + model::BlipFill* pBlipFill = nullptr; + if (pFillStyle) + { + pFillStyle->mpFill = std::make_unique<model::BlipFill>(); + pBlipFill = static_cast<model::BlipFill*>(pFillStyle->mpFill.get()); + } + return new BlipFillContext( rParent, rAttribs, rFillProps.maBlipProps, pBlipFill); } case A_TOKEN( grpFill ): { diff --git a/oox/source/drawingml/textparagraphpropertiescontext.cxx b/oox/source/drawingml/textparagraphpropertiescontext.cxx index e75d65913cd9..2146d9ed04b0 100644 --- a/oox/source/drawingml/textparagraphpropertiescontext.cxx +++ b/oox/source/drawingml/textparagraphpropertiescontext.cxx @@ -275,7 +275,7 @@ ContextHandlerRef TextParagraphPropertiesContext::onCreateContext( sal_Int32 aEl case A_TOKEN( buBlip ): // CT_TextBlipBullet { mxBlipProps = std::make_shared<BlipFillProperties>(); - return new BlipFillContext( *this, rAttribs, *mxBlipProps ); + return new BlipFillContext(*this, rAttribs, *mxBlipProps, nullptr); } case A_TOKEN( tabLst ): // CT_TextTabStopList return new TextTabStopListContext( *this, maTabList );