summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorArmin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de>2023-06-05 17:15:34 +0200
committerAndras Timar <andras.timar@collabora.com>2023-06-09 12:25:11 +0200
commit0f948fc383c716cd6583969b258805c3501589ba (patch)
tree1ef4bd2a717b0b6f2c57c1587336b3838136d5f2 /oox
parent2c8002555a9b288b756d1af0f69656bbace36e6c (diff)
MCGR: tdf#155479 repair gradient SVG export for MCGR
Unfortunately SVG export is based on metafiles and thus there is (in principle) no way to get the BGradient/ColorStop/MCGR data transfered as needed. For that, using UNO API to read the model or using B2DPrimitives would help - as is better for the export respectively. Since there is not the time to re-design SVG export I added this 'compromize' as a fix. It gets the needed data transported over the metafile (that part is the compromize). It then exports the MCGR data to SVG (at least - as was already there - if it's a linear/axial gradient). This happens now with all Gradient Stops when there is a MCGR gradient. That part is/will hopefully be re-usable if SVG export gets redesigned. I also added a handling for StepCount feature, so when used (in LO, others do not have that) 'hard' color stops get generated to make the gradient look identical for SVG export. Had to make adding of that extra-information in metafiles dependent on exporting really to SVG. There are 51 cases which use 'MetaActionType::COMMENT' which would potentially have to be adapted. Also added code to solve the problem for TransparencePrimitive2D at VclMetafileProcessor2D::processTransparencePrimitive2D. This will now - also only for SVG export - directly create the needed MetaFloatTransparentAction and add additional MCGR information. This will be used on SVG export to write a 'Mask' as was done before. This is now capable of creating fill MCGR-Masks in the sense that any number of TransparencyStops will be supported. Change-Id: Ic6d022714eae96b8fbc09e60652851ac5799b757 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152623 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/export/drawingml.cxx58
1 files changed, 15 insertions, 43 deletions
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 7771caa7c92f..6599f6cb1959 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -747,7 +747,16 @@ void DrawingML::WriteGradientFill(
basegfx::utils::prepareColorStops(*pTransparenceGradient, aAlphaStops, aSingleAlpha);
}
- // synchronize ColorStops and AlphaStops as peparation to export
+ // apply steps if used. Need to do that before synchronizeColorStops
+ // since that may add e.g. for AlphaStops all-the-same no-data entries,
+ // so the number of entries might change
+ if (pGradient->GetSteps())
+ {
+ aColorStops.doApplySteps(pGradient->GetSteps());
+ aAlphaStops.doApplySteps(pGradient->GetSteps());
+ }
+
+ // synchronize ColorStops and AlphaStops as preparation to export
// so also gradients 'coupled' indirectly using the 'FillTransparenceGradient'
// method (at import time) will be exported again
basegfx::utils::synchronizeColorStops(aColorStops, aAlphaStops, aSingleColor, aSingleAlpha);
@@ -776,48 +785,11 @@ void DrawingML::WriteGradientFill(
}
case awt::GradientStyle_AXIAL:
{
- // we need to 'double' the gradient to make it appear as what we call
- // 'axial', but also scale and mirror in doing so
- basegfx::BColorStops aNewColorStops;
- basegfx::BColorStops aNewAlphaStops;
-
- // add mirrored gradients, scaled to [0.0 .. 0.5]
- basegfx::BColorStops::const_reverse_iterator aRevCurrColor(aColorStops.rbegin());
- basegfx::BColorStops::const_reverse_iterator aRevCurrAlpha(aAlphaStops.rbegin());
-
- while (aRevCurrColor != aColorStops.rend() && aRevCurrAlpha != aAlphaStops.rend())
- {
- aNewColorStops.emplace_back((1.0 - aRevCurrColor->getStopOffset()) * 0.5, aRevCurrColor->getStopColor());
- aNewAlphaStops.emplace_back((1.0 - aRevCurrAlpha->getStopOffset()) * 0.5, aRevCurrAlpha->getStopColor());
- aRevCurrColor++;
- aRevCurrAlpha++;
- }
-
- basegfx::BColorStops::const_iterator aCurrColor(aColorStops.begin());
- basegfx::BColorStops::const_iterator aCurrAlpha(aAlphaStops.begin());
-
- if (basegfx::fTools::equalZero(aCurrColor->getStopOffset()))
- {
- // Caution: do not add 1st entry again, that would be double since it was
- // already added as last element of the inverse run above. But only if
- // the gradient has a start entry for 0.0 aka StartColor, else it is correct.
- // Since aColorStops and aAlphaStops are already syched (see
- // synchronizeColorStops above), testing one of them is sufficient here.
- aCurrColor++;
- aCurrAlpha++;
- }
-
- // add non-mirrored gradients, translated and scaled to [0.5 .. 1.0]
- while (aCurrColor != aColorStops.end() && aCurrAlpha != aAlphaStops.end())
- {
- aNewColorStops.emplace_back((aCurrColor->getStopOffset() * 0.5) + 0.5, aCurrColor->getStopColor());
- aNewAlphaStops.emplace_back((aCurrAlpha->getStopOffset() * 0.5) + 0.5, aCurrAlpha->getStopColor());
- aCurrColor++;
- aCurrAlpha++;
- }
-
- aColorStops = aNewColorStops;
- aAlphaStops = aNewAlphaStops;
+ // use tooling to convert from GradientStyle_AXIAL to GradientStyle_LINEAR
+ // NOTE: Since aColorStops and aAlphaStops are already synched (see
+ // synchronizeColorStops above) this can be done directly here
+ aColorStops.doApplyAxial();
+ aAlphaStops.doApplyAxial();
// remember being axial
bAxial = true;