diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2020-07-14 22:52:56 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-08-07 10:29:11 +0200 |
commit | 0ff6f5ad44a5fb9903c9a905d2ec55248ee75315 (patch) | |
tree | 7a08bbec2df1343eb07efd6f357c95264eafff12 /oox | |
parent | Resolves: tdf#135249 Duration input 0:123 or 0:0:123 or 0:123:59 is valid (diff) | |
download | core-0ff6f5ad44a5fb9903c9a905d2ec55248ee75315.tar.gz core-0ff6f5ad44a5fb9903c9a905d2ec55248ee75315.zip |
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.
(cherry picked from commit d187f22b7ff73954e1da39fb954c64bc315298cb)
Conflicts:
oox/source/drawingml/fillproperties.cxx
sd/qa/unit/export-tests-ooxml1.cxx
Change-Id: I4243656821629f90125d0408a38165a8a29e6e24
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100286
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
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 caa54b82ca34..f963f103d2c8 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -529,10 +529,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 327d5a27931a..b9c6403caff2 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -405,8 +405,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 ); @@ -586,25 +616,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), @@ -619,23 +649,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); @@ -648,15 +677,19 @@ void DrawingML::WriteGradientFill(awt::Gradient rGradient, awt::Gradient rTransp case awt::GradientStyle_RADIAL: { 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); WriteRadialGradientPath(rGradient, mpFS); @@ -3468,14 +3501,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 ) { |