summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorTamas Bunth <tamas.bunth@collabora.co.uk>2020-01-21 19:04:13 +0100
committerTamás Bunth <btomi96@gmail.com>2020-03-03 15:52:47 +0100
commitf9fc420dceb1ece2c98767da16a21aaff771f140 (patch)
tree299b9c856a3567ee85af11b7b314d2d02a03420b /oox
parent224ab38f747dcafe711c10b54ad53c52bda9e41d (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.cxx7
-rw-r--r--oox/source/drawingml/effectproperties.hxx10
-rw-r--r--oox/source/drawingml/effectpropertiescontext.cxx13
-rw-r--r--oox/source/drawingml/shape.cxx10
-rw-r--r--oox/source/export/drawingml.cxx67
-rw-r--r--oox/source/token/properties.txt2
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