summaryrefslogtreecommitdiffstats
path: root/oox
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2020-07-14 22:52:56 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-08-07 10:29:11 +0200
commit0ff6f5ad44a5fb9903c9a905d2ec55248ee75315 (patch)
tree7a08bbec2df1343eb07efd6f357c95264eafff12 /oox
parentResolves: tdf#135249 Duration input 0:123 or 0:0:123 or 0:123:59 is valid (diff)
downloadcore-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.cxx6
-rw-r--r--oox/source/export/drawingml.cxx106
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 )
{