diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2019-07-01 21:10:01 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2019-07-02 09:06:37 +0200 |
commit | 599ae1151bf893491db7ad983d64c77521c3ae9d (patch) | |
tree | a3d67407d93b694c48a6660991bfc9d387a996d8 /oox/source | |
parent | 7d32994ad9dc45c7846664ec5ccb03bb796bb071 (diff) |
tdf#125554 PPTX export: handle gradient transparency for gradient fill
Regression from commit cfc1f4ea4889f768d689a0df71519e9bcb707bc0 (oox:
disable gradient fill grab-bag for PPTX, 2019-02-05), the problem was
that in the past grab-bag roundtrip worked (in some cases) for this
shape fill case, but true roundtrip did not.
So when the commit disabled grab-bags (since their color pointers in the
theme don't work in the PPTX case), a previously not implemented feature
now started causing a real problem.
Fix the bug by adding support for transparent linear gradients on the
exports side. This means that in case the import creates both a fill
gradient and a transparency gradient, then now the export creates markup
based on both, not only based on the fill gradient.
Change-Id: I99fa3caba2b2884c2acb7e0704bbeb0b6cffd4a4
Reviewed-on: https://gerrit.libreoffice.org/74968
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'oox/source')
-rw-r--r-- | oox/source/export/drawingml.cxx | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 11d900e28794..08cbf8b796fd 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -132,6 +132,17 @@ using ::css::io::XOutputStream; using ::sax_fastparser::FSHelperPtr; using ::sax_fastparser::FastSerializerHelper; +namespace +{ +/// Extracts start or end alpha information from a transparency gradient. +sal_Int32 GetAlphaFromTransparenceGradient(const awt::Gradient& rGradient, bool bStart) +{ + // Our alpha is a gray color value. + sal_uInt8 nRed = ::Color(bStart ? rGradient.StartColor : rGradient.EndColor).GetRed(); + // drawingML alpha is a percentage on a 0..100000 scale. + return (255 - nRed) * oox::drawingml::MAX_PERCENT / 255; +} +} namespace oox { namespace drawingml { @@ -415,10 +426,10 @@ void DrawingML::WriteSolidFill( const Reference< XPropertySet >& rXPropSet ) } } -void DrawingML::WriteGradientStop( sal_uInt16 nStop, ::Color nColor ) +void DrawingML::WriteGradientStop(sal_uInt16 nStop, ::Color nColor, sal_Int32 nAlpha) { mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(nStop * 1000)); - WriteColor( nColor ); + WriteColor(nColor, nAlpha); mpFS->endElementNS( XML_a, XML_gs ); } @@ -480,7 +491,7 @@ void DrawingML::WriteGradientFill( const Reference< XPropertySet >& rXPropSet ) else { mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape, "0"); - WriteGradientFill(aGradient); + WriteGradientFill(aGradient, rXPropSet); mpFS->endElementNS( XML_a, XML_gradFill ); } } @@ -545,20 +556,40 @@ void DrawingML::WriteGrabBagGradientFill( const Sequence< PropertyValue >& aGrad } } -void DrawingML::WriteGradientFill( awt::Gradient rGradient ) +void DrawingML::WriteGradientFill(awt::Gradient rGradient, + const uno::Reference<beans::XPropertySet>& rXPropSet) { switch( rGradient.Style ) { default: case awt::GradientStyle_LINEAR: + { + awt::Gradient aTransparenceGradient; + bool bTransparent = false; + if (rXPropSet.is() && GetProperty(rXPropSet, "FillTransparenceGradient")) + { + aTransparenceGradient = *o3tl::doAccess<awt::Gradient>(mAny); + bTransparent = true; + } + mpFS->startElementNS(XML_a, XML_gsLst); - WriteGradientStop( 0, ColorWithIntensity( rGradient.StartColor, rGradient.StartIntensity ) ); - WriteGradientStop( 100, ColorWithIntensity( rGradient.EndColor, rGradient.EndIntensity ) ); + sal_Int32 nStartAlpha = MAX_PERCENT; + sal_Int32 nEndAlpha = MAX_PERCENT; + if (bTransparent) + { + nStartAlpha = GetAlphaFromTransparenceGradient(aTransparenceGradient, true); + nEndAlpha = GetAlphaFromTransparenceGradient(aTransparenceGradient, false); + } + WriteGradientStop(0, ColorWithIntensity(rGradient.StartColor, rGradient.StartIntensity), + nStartAlpha); + WriteGradientStop(100, ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity), + nEndAlpha); mpFS->endElementNS( XML_a, XML_gsLst ); mpFS->singleElementNS( XML_a, XML_lin, XML_ang, OString::number((((3600 - rGradient.Angle + 900) * 6000) % 21600000))); break; + } case awt::GradientStyle_AXIAL: mpFS->startElementNS(XML_a, XML_gsLst); |