diff options
author | Tamas Bunth <tamas.bunth@collabora.co.uk> | 2020-01-21 19:04:13 +0100 |
---|---|---|
committer | Tamás Bunth <btomi96@gmail.com> | 2020-03-03 15:52:47 +0100 |
commit | f9fc420dceb1ece2c98767da16a21aaff771f140 (patch) | |
tree | 299b9c856a3567ee85af11b7b314d2d02a03420b /oox | |
parent | 224ab38f747dcafe711c10b54ad53c52bda9e41d (diff) |
tdf#101181 Implement glow effect on shapes
Glow effect is a color-blurred outline outside of the shape. In ooxml
document it is specified with the <a:glow> element.
The commit contains the following:
- Add support for importing and exporting <a:glow> from ooxml documents.
- Assign new properties to XShape which stores glow-related attributes.
- A new 2D primitive is introduced in module 'drawinglayer' which is
responsible for representing the glow primitive which is to be rendered.
+ A glow primitive is a clone of the original shape which has been
scaled up slightly and a new color has been assigned to it. The
radius of the glow effect and the color is defined in the <a:glow>
element being imported.
- A blur algorithm is introduced in module 'vcl', which is called during
rendering the primitive.
+ The blur algorithm works on a bitmap.
+ Since the algorithm is CPU-intensive, the result is cached in the
processor and it is recalculated only if needed.
- Add support for importing and exporting glow effect to ODF format. For
that, new attributes of element <style:graphic-properties> has been
added:
+ loext:glow, which can have the values "visible" or "hidden"
+ loext:glow-radius: which holds the radius of the glow effect in cm.
+ loext:glow-color: holds the color of the glow effect
- Tests have been added to assert properties after pptx import and
export.
Change-Id: I836aeb5e0f24e2c8d5725834c8c0f98083bc82e7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89125
Tested-by: Jenkins
Reviewed-by: Tamás Bunth <btomi96@gmail.com>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/effectproperties.cxx | 7 | ||||
-rw-r--r-- | oox/source/drawingml/effectproperties.hxx | 10 | ||||
-rw-r--r-- | oox/source/drawingml/effectpropertiescontext.cxx | 13 | ||||
-rw-r--r-- | oox/source/drawingml/shape.cxx | 10 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 67 | ||||
-rw-r--r-- | oox/source/token/properties.txt | 2 |
6 files changed, 88 insertions, 21 deletions
diff --git a/oox/source/drawingml/effectproperties.cxx b/oox/source/drawingml/effectproperties.cxx index 2ca45bae05a8..e4e9eaddcb32 100644 --- a/oox/source/drawingml/effectproperties.cxx +++ b/oox/source/drawingml/effectproperties.cxx @@ -18,6 +18,12 @@ namespace oox::drawingml { +void EffectGlowProperties ::assignUsed(const EffectGlowProperties& rSourceProps) +{ + moGlowRad.assignIfUsed( rSourceProps.moGlowRad ); + moGlowColor.assignIfUsed( rSourceProps.moGlowColor ); +} + void EffectShadowProperties::assignUsed(const EffectShadowProperties& rSourceProps) { moShadowDist.assignIfUsed( rSourceProps.moShadowDist ); @@ -28,6 +34,7 @@ void EffectShadowProperties::assignUsed(const EffectShadowProperties& rSourcePro void EffectProperties::assignUsed( const EffectProperties& rSourceProps ) { maShadow.assignUsed(rSourceProps.maShadow); + maGlow.assignUsed(rSourceProps.maGlow); if (!rSourceProps.m_Effects.empty()) { m_Effects.clear(); diff --git a/oox/source/drawingml/effectproperties.hxx b/oox/source/drawingml/effectproperties.hxx index 146214cc9191..c4f39ac8803b 100644 --- a/oox/source/drawingml/effectproperties.hxx +++ b/oox/source/drawingml/effectproperties.hxx @@ -20,6 +20,15 @@ namespace oox { namespace drawingml { +struct EffectGlowProperties +{ + OptValue< sal_Int64 > moGlowRad; // size of glow effect + Color moGlowColor; + // TODO saturation and luminance missing + + void assignUsed( const EffectGlowProperties& rSourceProps ); +}; + struct EffectShadowProperties { OptValue< sal_Int64 > moShadowDist; @@ -42,6 +51,7 @@ struct Effect struct EffectProperties { EffectShadowProperties maShadow; + EffectGlowProperties maGlow; /** Stores all effect properties, including those not supported by core yet */ std::vector<std::unique_ptr<Effect>> m_Effects; diff --git a/oox/source/drawingml/effectpropertiescontext.cxx b/oox/source/drawingml/effectpropertiescontext.cxx index 7941920ed370..6424e99d8458 100644 --- a/oox/source/drawingml/effectpropertiescontext.cxx +++ b/oox/source/drawingml/effectpropertiescontext.cxx @@ -15,6 +15,8 @@ #include <oox/token/namespaces.hxx> #include <oox/token/tokens.hxx> +#include <sal/log.hxx> + using namespace ::oox::core; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::xml::sax; @@ -97,13 +99,18 @@ ContextHandlerRef EffectPropertiesContext::onCreateContext( sal_Int32 nElement, } break; case A_TOKEN( glow ): + { + mrEffectProperties.maGlow.moGlowRad = rAttribs.getInteger( XML_rad, 0 ); + // undo push_back to effects + mrEffectProperties.m_Effects.pop_back(); + return new ColorContext(*this, mrEffectProperties.maGlow.moGlowColor); + + } case A_TOKEN( softEdge ): case A_TOKEN( reflection ): case A_TOKEN( blur ): { - if( nElement == A_TOKEN( glow ) ) - mrEffectProperties.m_Effects[nPos]->msName = "glow"; - else if( nElement == A_TOKEN( softEdge ) ) + if( nElement == A_TOKEN( softEdge ) ) mrEffectProperties.m_Effects[nPos]->msName = "softEdge"; else if( nElement == A_TOKEN( reflection ) ) mrEffectProperties.m_Effects[nPos]->msName = "reflection"; diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 0cf633369959..1c307ff38371 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -1215,6 +1215,7 @@ Reference< XShape > const & Shape::createAndInsert( aFormat.ShadowWidth = *oShadowDistance; aShapeProps.setProperty(PROP_ShadowFormat, aFormat); } + } else if (mbTextBox) { @@ -1464,6 +1465,15 @@ Reference< XShape > const & Shape::createAndInsert( aPropertySet.setAnyProperty(PROP_CharColor, uno::makeAny(nCharColor)); } } + + // Set glow effect properties + if ( aEffectProperties.maGlow.moGlowRad.has() ) + { + uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY); + propertySet->setPropertyValue("GlowEffect", makeAny(true)); + propertySet->setPropertyValue("GlowEffectRad", makeAny(static_cast<sal_Int32>(aEffectProperties.maGlow.moGlowRad.get()))); + propertySet->setPropertyValue("GlowEffectColor", makeAny(aEffectProperties.maGlow.moGlowColor.getColor(rGraphicHelper))); + } } if( mxShape.is() ) diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index b4c37d514ece..d80b6a3bea7e 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -3719,29 +3719,38 @@ void DrawingML::WriteShapeEffects( const Reference< XPropertySet >& rXPropSet ) bool bHasShadow = false; if( GetProperty( rXPropSet, "Shadow" ) ) mAny >>= bHasShadow; - if( bHasShadow ) + bool bHasGlow = false; + if( GetProperty( rXPropSet, "GlowEffect") ) + mAny >>= bHasGlow; + //rXPropSet->getPropertyValue("GlowEffect") >>= bHasGlow; + + if( bHasShadow || bHasGlow ) { - Sequence< PropertyValue > aShadowGrabBag( 3 ); - Sequence< PropertyValue > aShadowAttribsGrabBag( 2 ); + mpFS->startElementNS(XML_a, XML_effectLst); + if( bHasShadow ) + { + Sequence< PropertyValue > aShadowGrabBag( 3 ); + Sequence< PropertyValue > aShadowAttribsGrabBag( 2 ); - double dX = +0.0, dY = +0.0; - rXPropSet->getPropertyValue( "ShadowXDistance" ) >>= dX; - rXPropSet->getPropertyValue( "ShadowYDistance" ) >>= dY; + double dX = +0.0, dY = +0.0; + rXPropSet->getPropertyValue( "ShadowXDistance" ) >>= dX; + rXPropSet->getPropertyValue( "ShadowYDistance" ) >>= dY; - aShadowAttribsGrabBag[0].Name = "dist"; - aShadowAttribsGrabBag[0].Value <<= lcl_CalculateDist(dX, dY); - aShadowAttribsGrabBag[1].Name = "dir"; - aShadowAttribsGrabBag[1].Value <<= lcl_CalculateDir(dX, dY); + aShadowAttribsGrabBag[0].Name = "dist"; + aShadowAttribsGrabBag[0].Value <<= lcl_CalculateDist(dX, dY); + aShadowAttribsGrabBag[1].Name = "dir"; + aShadowAttribsGrabBag[1].Value <<= lcl_CalculateDir(dX, dY); - aShadowGrabBag[0].Name = "Attribs"; - aShadowGrabBag[0].Value <<= aShadowAttribsGrabBag; - aShadowGrabBag[1].Name = "RgbClr"; - aShadowGrabBag[1].Value = rXPropSet->getPropertyValue( "ShadowColor" ); - aShadowGrabBag[2].Name = "RgbClrTransparency"; - aShadowGrabBag[2].Value = rXPropSet->getPropertyValue( "ShadowTransparence" ); + aShadowGrabBag[0].Name = "Attribs"; + aShadowGrabBag[0].Value <<= aShadowAttribsGrabBag; + aShadowGrabBag[1].Name = "RgbClr"; + aShadowGrabBag[1].Value = rXPropSet->getPropertyValue( "ShadowColor" ); + aShadowGrabBag[2].Name = "RgbClrTransparency"; + aShadowGrabBag[2].Value = rXPropSet->getPropertyValue( "ShadowTransparence" ); - mpFS->startElementNS(XML_a, XML_effectLst); - WriteShapeEffect( "outerShdw", aShadowGrabBag ); + WriteShapeEffect( "outerShdw", aShadowGrabBag ); + } + WriteGlowEffect(rXPropSet); mpFS->endElementNS(XML_a, XML_effectLst); } } @@ -3796,10 +3805,32 @@ void DrawingML::WriteShapeEffects( const Reference< XPropertySet >& rXPropSet ) WriteShapeEffect( rEffect.Name, aEffectProps ); } } + WriteGlowEffect(rXPropSet); + mpFS->endElementNS(XML_a, XML_effectLst); } } +void DrawingML::WriteGlowEffect(const Reference< XPropertySet >& rXPropSet) +{ + bool hasGlow = false; + rXPropSet->getPropertyValue("GlowEffect") >>= hasGlow; + if(!hasGlow) + return; + + Sequence< PropertyValue > aGlowAttribs(1); + aGlowAttribs[0].Name = "rad"; + aGlowAttribs[0].Value = rXPropSet->getPropertyValue("GlowEffectRad"); + Sequence< PropertyValue > aGlowProps(2); + aGlowProps[0].Name = "Attribs"; + aGlowProps[0].Value <<= aGlowAttribs; + aGlowProps[1].Name = "RgbClr"; + aGlowProps[1].Value = rXPropSet->getPropertyValue("GlowEffectColor"); + // TODO other stuff like saturation or luminance + + WriteShapeEffect("glow", aGlowProps); +} + void DrawingML::WriteShape3DEffects( const Reference< XPropertySet >& xPropSet ) { // check existence of the grab bag diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index 4fc0c5b47c57..4624573d579b 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -207,6 +207,8 @@ Function GapwidthSequence GenerateVbaEvents Geometry3D +GlowEffect +GlowEffectRad GradientName HatchName Graphic |