diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2019-02-04 17:34:39 +0100 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2019-02-05 13:23:52 +0100 |
commit | 30e934dfa61f798ab0e7f1675f201063d97d89dd (patch) | |
tree | d7585b375ff813ef07b97c31369b81fd4f1fdc5c /oox | |
parent | f4999d0e3eae63f9b00c7e809f55a99fe596e8e2 (diff) |
Related: tdf#94238 PPTX export: handle border and center of radial gradient
Map Border to a gradient stop before the final one.
Map X/YOffset to the focus rectangle of the center shade, i.e. the
opposite of what the import already does.
(cherry picked from commit 82365563fb2fd55d90d444a104fa475d4ffc4cf1)
Conflicts:
oox/source/export/drawingml.cxx
sd/qa/unit/import-tests.cxx
Change-Id: I88db7d579da7327e5e06b736a75a6892b338dd73
Reviewed-on: https://gerrit.libreoffice.org/67395
Reviewed-by: Jan Holesovsky <kendy@collabora.com>
Tested-by: Jan Holesovsky <kendy@collabora.com>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/export/drawingml.cxx | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 302abe723545..9bcf08305afd 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -130,6 +130,33 @@ namespace drawingml { #define CGETAD(propName) \ (( bCheckDirect && GetPropertyAndState( rXPropSet, rXPropState, #propName, eState ) && eState == beans::PropertyState_DIRECT_VALUE )||GetProperty( rXPropSet, #propName )) +namespace +{ +void WriteRadialGradientPath(const awt::Gradient& rGradient, const FSHelperPtr& pFS) +{ + pFS->startElementNS(XML_a, XML_path, XML_path, "circle", FSEND); + + // Write the focus rectangle. Work with the focus point, and assume + // that it extends 50% in all directions. The below + // left/top/right/bottom values are percentages, where 0 means the + // edge of the tile rectangle and 100% means the center of it. + rtl::Reference<sax_fastparser::FastAttributeList> pAttributeList( + sax_fastparser::FastSerializerHelper::createAttrList()); + sal_Int32 nLeftPercent = rGradient.XOffset * 2 - 50; + pAttributeList->add(XML_l, OString::number(nLeftPercent * PER_PERCENT)); + sal_Int32 nTopPercent = rGradient.YOffset * 2 - 50; + pAttributeList->add(XML_t, OString::number(nTopPercent * PER_PERCENT)); + sal_Int32 nRightPercent = (100 - rGradient.XOffset) * 2 - 50; + pAttributeList->add(XML_r, OString::number(nRightPercent * PER_PERCENT)); + sal_Int32 nBottomPercent = (100 - rGradient.YOffset) * 2 - 50; + pAttributeList->add(XML_b, OString::number(nBottomPercent * PER_PERCENT)); + sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList.get()); + pFS->singleElementNS(XML_a, XML_fillToRect, xAttributeList); + + pFS->endElementNS(XML_a, XML_path); +} +} + // not thread safe int DrawingML::mnImageCounter = 1; int DrawingML::mnWdpImageCounter = 1; @@ -447,9 +474,17 @@ void DrawingML::WriteGrabBagGradientFill( const Sequence< PropertyValue >& aGrad } mpFS->endElementNS( XML_a, XML_gsLst ); - mpFS->singleElementNS( XML_a, XML_lin, - XML_ang, I32S( ( ( ( 3600 - rGradient.Angle + 900 ) * 6000 ) % 21600000 ) ), - FSEND ); + switch (rGradient.Style) + { + default: + mpFS->singleElementNS( XML_a, XML_lin, + XML_ang, I32S( ( ( ( 3600 - rGradient.Angle + 900 ) * 6000 ) % 21600000 ) ), + FSEND ); + break; + case awt::GradientStyle_RADIAL: + WriteRadialGradientPath(rGradient, mpFS); + break; + } } void DrawingML::WriteGradientFill( awt::Gradient rGradient ) @@ -478,10 +513,26 @@ void DrawingML::WriteGradientFill( awt::Gradient rGradient ) FSEND ); break; + case awt::GradientStyle_RADIAL: + { + mpFS->startElementNS(XML_a, XML_gsLst, FSEND); + WriteGradientStop(0, ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity)); + 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, + ColorWithIntensity(rGradient.StartColor, rGradient.StartIntensity)); + mpFS->endElementNS(XML_a, XML_gsLst); + + WriteRadialGradientPath(rGradient, mpFS); + break; + } /* I don't see how to apply transformation to gradients, so * elliptical will end as radial and square as * rectangular. also position offsets are not applied */ - case awt::GradientStyle_RADIAL: case awt::GradientStyle_ELLIPTICAL: case awt::GradientStyle_RECT: case awt::GradientStyle_SQUARE: |