diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2020-07-14 22:52:56 +0200 |
---|---|---|
committer | Regina Henschel <rb.henschel@t-online.de> | 2020-07-18 16:29:37 +0200 |
commit | d187f22b7ff73954e1da39fb954c64bc315298cb (patch) | |
tree | 6165794772de6d1bd32e7b68b1f0211db499f4c8 /oox | |
parent | 9712e25425e22b59afce82f26a14a48ebb37cd38 (diff) |
tdf#128345 pptx export: add transparence gradient in solid fill
In case of solid color fill a transparence gradient was not saved.
OOXML has no separate element for gradient transparency but has
transparency in color gradient stop elements. The patch detects
a transparence gradient, combines it with the fill color and exports
it as gradFill element.
The import was already correct, besides a wrong start or end value
in case of a symmetric gradient, which becomes AXIAL in LibreOffice.
Change-Id: I4243656821629f90125d0408a38165a8a29e6e24
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98792
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/fillproperties.cxx | 6 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 106 |
2 files changed, 75 insertions, 37 deletions
diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx index 963c4009becf..f203e9e2823e 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -537,10 +537,8 @@ void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap, aGradient.StartColor = sal_Int32(aStartColor.getColor( rGraphicHelper, nPhClr )); aGradient.EndColor = sal_Int32(aEndColor.getColor( rGraphicHelper, nPhClr )); - if( aStartColor.hasTransparency() ) - nStartTrans = aStartColor.getTransparency()*255/100; - if( aEndColor.hasTransparency() ) - nEndTrans = aEndColor.getTransparency()*255/100; + nStartTrans = aStartColor.hasTransparency() ? aStartColor.getTransparency()*255/100 : 0; + nEndTrans = aEndColor.hasTransparency() ? aEndColor.getTransparency()*255/100 : 0; aGradient.Border = rtl::math::round(100*nBorder); } diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 847bee54ab97..517d9801bba6 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -398,8 +398,38 @@ void DrawingML::WriteSolidFill( const Reference< XPropertySet >& rXPropSet ) nAlpha = (MAX_PERCENT - ( PER_PERCENT * nTransparency ) ); } + // OOXML has no separate transparence gradient but uses transparency in the gradient stops. + // So we merge transparency and color and use gradient fill in such case. + awt::Gradient aTransparenceGradient; + bool bNeedGradientFill(false); + if (GetProperty(rXPropSet, "FillTransparenceGradient")) + { + mAny >>= aTransparenceGradient; + if (aTransparenceGradient.StartColor != aTransparenceGradient.EndColor) + bNeedGradientFill = true; + else if (aTransparenceGradient.StartColor != 0) + nAlpha = GetAlphaFromTransparenceGradient(aTransparenceGradient, true); + } + // write XML - if ( nFillColor != nOriginalColor ) + if (bNeedGradientFill) + { + awt::Gradient aPseudoColorGradient; + aPseudoColorGradient.XOffset = aTransparenceGradient.XOffset; + aPseudoColorGradient.YOffset = aTransparenceGradient.YOffset; + aPseudoColorGradient.StartIntensity = 100; + aPseudoColorGradient.EndIntensity = 100; + aPseudoColorGradient.Angle = aTransparenceGradient.Angle; + aPseudoColorGradient.Border = aTransparenceGradient.Border; + aPseudoColorGradient.Style = aTransparenceGradient.Style; + aPseudoColorGradient.StartColor = nFillColor; + aPseudoColorGradient.EndColor = nFillColor; + aPseudoColorGradient.StepCount = aTransparenceGradient.StepCount; + mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape, "0"); + WriteGradientFill(aPseudoColorGradient, aTransparenceGradient); + mpFS->endElementNS( XML_a, XML_gradFill ); + } + else if ( nFillColor != nOriginalColor ) { // the user has set a different color for the shape WriteSolidFill( ::Color(nFillColor & 0xffffff), nAlpha ); @@ -579,25 +609,25 @@ void DrawingML::WriteGrabBagGradientFill( const Sequence< PropertyValue >& aGrad void DrawingML::WriteGradientFill(awt::Gradient rGradient, awt::Gradient rTransparenceGradient, const uno::Reference<beans::XPropertySet>& rXPropSet) { + sal_Int32 nStartAlpha; + sal_Int32 nEndAlpha; + if( rXPropSet.is() && GetProperty(rXPropSet, "FillTransparence") ) + { + sal_Int32 nTransparency = 0; + mAny >>= nTransparency; + nStartAlpha = nEndAlpha = (MAX_PERCENT - (PER_PERCENT * nTransparency)); + } + else + { + nStartAlpha = GetAlphaFromTransparenceGradient(rTransparenceGradient, true); + nEndAlpha = GetAlphaFromTransparenceGradient(rTransparenceGradient, false); + } switch( rGradient.Style ) { default: case awt::GradientStyle_LINEAR: { mpFS->startElementNS(XML_a, XML_gsLst); - sal_Int32 nStartAlpha; - sal_Int32 nEndAlpha; - if( rXPropSet.is() && GetProperty(rXPropSet, "FillTransparence") ) - { - sal_Int32 nTransparency = 0; - mAny >>= nTransparency; - nStartAlpha = nEndAlpha = (MAX_PERCENT - (PER_PERCENT * nTransparency)); - } - else - { - nStartAlpha = GetAlphaFromTransparenceGradient(rTransparenceGradient, true); - nEndAlpha = GetAlphaFromTransparenceGradient(rTransparenceGradient, false); - } WriteGradientStop(rGradient.Border, ColorWithIntensity(rGradient.StartColor, rGradient.StartIntensity), nStartAlpha); WriteGradientStop(100, ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity), @@ -612,23 +642,22 @@ void DrawingML::WriteGradientFill(awt::Gradient rGradient, awt::Gradient rTransp case awt::GradientStyle_AXIAL: { mpFS->startElementNS(XML_a, XML_gsLst); - sal_Int32 nStartAlpha; - sal_Int32 nEndAlpha; - if (rXPropSet.is() && GetProperty(rXPropSet, "FillTransparence")) - { - sal_Int32 nTransparency = 0; - mAny >>= nTransparency; - nStartAlpha = nEndAlpha = (MAX_PERCENT - (PER_PERCENT * nTransparency)); - } - else - { - nStartAlpha = GetAlphaFromTransparenceGradient(rTransparenceGradient, true); - nEndAlpha = GetAlphaFromTransparenceGradient(rTransparenceGradient, false); - } WriteGradientStop(0, ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity), nEndAlpha); + if (rGradient.Border > 0 && rGradient.Border < 100) + { + WriteGradientStop(rGradient.Border/2, + ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity), + nEndAlpha); + } WriteGradientStop(50, ColorWithIntensity(rGradient.StartColor, rGradient.StartIntensity), nStartAlpha); + if (rGradient.Border > 0 && rGradient.Border < 100) + { + WriteGradientStop(100 - rGradient.Border/2, + ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity), + nEndAlpha); + } WriteGradientStop(100, ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity), nEndAlpha); mpFS->endElementNS(XML_a, XML_gsLst); @@ -644,15 +673,19 @@ void DrawingML::WriteGradientFill(awt::Gradient rGradient, awt::Gradient rTransp case awt::GradientStyle_SQUARE: { mpFS->startElementNS(XML_a, XML_gsLst); - WriteGradientStop(0, ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity)); + WriteGradientStop(0, ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity), + nEndAlpha); if (rGradient.Border > 0 && rGradient.Border < 100) + { // Map border to an additional gradient stop, which has the // same color as the final stop. - WriteGradientStop( - 100 - rGradient.Border, - ColorWithIntensity(rGradient.StartColor, rGradient.StartIntensity)); + WriteGradientStop(100 - rGradient.Border, + ColorWithIntensity(rGradient.StartColor, rGradient.StartIntensity), + nStartAlpha); + } WriteGradientStop(100, - ColorWithIntensity(rGradient.StartColor, rGradient.StartIntensity)); + ColorWithIntensity(rGradient.StartColor, rGradient.StartIntensity), + nStartAlpha); mpFS->endElementNS(XML_a, XML_gsLst); WriteGradientPath(rGradient, mpFS, rGradient.Style == awt::GradientStyle_RADIAL || rGradient.Style == awt::GradientStyle_ELLIPTICAL); @@ -3564,14 +3597,21 @@ void DrawingML::WriteFill( const Reference< XPropertySet >& xPropSet ) FillStyle aFillStyle( FillStyle_NONE ); xPropSet->getPropertyValue( "FillStyle" ) >>= aFillStyle; + // map full transparent background to no fill if ( aFillStyle == FillStyle_SOLID && GetProperty( xPropSet, "FillTransparence" ) ) { - // map full transparent background to no fill sal_Int16 nVal = 0; xPropSet->getPropertyValue( "FillTransparence" ) >>= nVal; if ( nVal == 100 ) aFillStyle = FillStyle_NONE; } + if (aFillStyle == FillStyle_SOLID && GetProperty( xPropSet, "FillTransparenceGradient")) + { + awt::Gradient aTransparenceGradient; + mAny >>= aTransparenceGradient; + if (aTransparenceGradient.StartColor == 0xffffff && aTransparenceGradient.EndColor == 0xffffff) + aFillStyle = FillStyle_NONE; + } switch( aFillStyle ) { |