diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2019-02-04 17:34:39 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2019-06-18 15:43:11 +0200 |
commit | c7239345e707a36dbebe7dcb100974b6898cf293 (patch) | |
tree | e0b8bbaf95340ad321c333f3883df08577008716 /oox | |
parent | fda87834ae29dd0cba6cfc420c97ea79593c4738 (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
Reviewed-on: https://gerrit.libreoffice.org/67395
Reviewed-by: Jan Holesovsky <kendy@collabora.com>
Tested-by: Jan Holesovsky <kendy@collabora.com>
Conflicts:
oox/source/export/drawingml.cxx
sd/qa/unit/export-tests-ooxml1.cxx
sd/qa/unit/import-tests.cxx
Change-Id: I88db7d579da7327e5e06b736a75a6892b338dd73
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 0f4f75c155cc..b29fc4a5bc4b 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -162,6 +162,33 @@ static css::uno::Any getLineDash( const css::uno::Reference<css::frame::XModel>& } +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; @@ -511,9 +538,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 ) @@ -542,10 +577,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: |