summaryrefslogtreecommitdiff
path: root/oox/source/export
diff options
context:
space:
mode:
authorArmin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de>2023-04-21 15:18:09 +0200
committerArmin Le Grand <Armin.Le.Grand@me.com>2023-05-03 17:38:46 +0200
commitbb198176684c3d9377e26c04a29ec66deb811949 (patch)
tree731abe7ce1b95805900f39c6c7ac2c1c6ccfb211 /oox/source/export
parentf1fd3e32508ee3e8aca6f90724e7af8664652e41 (diff)
MCGR: Make MCGR default for oox im/export, cleanup
Following an error in CppunitTest_chart2_export3 I updated the transparency definition at WriteGradientFill and corrected usages. Had to correct/adapt some Chart UnitTests. Some of these changes are temporary since this will/has to change when ODF MCGR im/export is integrated. I checked that all of these cases actually work, comparing im LO and MSO. Adapted some Chart2ImportTest to directly compare/check now for the fully imported tranparence gradient with available higher precision. Adapted OoxDrawingmlTest testGradientMultiStepTransparency to use new MCGR capabilities. Adapted testTextframeGradient and tested the turn-around with rtf gradients. These are a little bit limited and needed some extra care. Adapted testTextframeGradient. Adapted SdOOXMLExportTest1, testTdf94238 Adapted SdOOXMLExportTest1, testTdf128345GradientAxial Adapted SdOOXMLExportTest2, testTdf105739 Adapted SdOOXMLExportTest3, testTdf127372 Adapted SdOOXMLExportTest3, testTdf127379 Adapted SdMiscTest, testFillGradient Adapted testTextframeGradient Adapted ScFiltersTest3, testTdf129789 Adapted SdUiImpressTest, testPageFillGradient Adapted SdOOXMLExportTest1, testTdf128345GradientLinear by using better double-to-integer rounding (basegfx::fround) in DrawingML::WriteGradientStop. After double calculations this makes the tansition to integer correct and stable. Also took back change at testTdf128345ChartArea_CG_TS_export which showed the same flaw before. 2nd look @testTdf128345Legend_CS_TG_axial_export made me add that stuff again and adapt the axial ColorStop adding in the export to not export the middle enty twice. Extended test a little bit, too. Only do not add value if it starts at 0.0 aka StartColor, else adding it is corect. Adapted some tests CPPUNIT_ASSERT to CPPUNIT_ASSERT_EQUAL after being pointed to it from gerrit_linux_clang_dbgutil build. Change-Id: I4a993053da8960035671b655e67908f36e59b5fe Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150763 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'oox/source/export')
-rw-r--r--oox/source/export/chartexport.cxx45
-rw-r--r--oox/source/export/drawingml.cxx205
2 files changed, 58 insertions, 192 deletions
diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx
index 94f956428d19..da8ef4924615 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -481,27 +481,6 @@ static sal_Int32 lcl_generateRandomValue()
return comphelper::rng::uniform_int_distribution(0, 100000000-1);
}
-static sal_Int32 lcl_getAlphaFromTransparenceGradient(const awt::Gradient2& rGradient, bool bStart)
-{
- // Our alpha is a gray color value.
- sal_uInt8 nRed(0);
-
- if (rGradient.ColorStops.getLength() > 0)
- {
- if (bStart)
- nRed = static_cast<sal_uInt8>(rGradient.ColorStops[0].StopColor.Red * 255.0);
- else
- nRed = static_cast<sal_uInt8>(rGradient.ColorStops[rGradient.ColorStops.getLength() - 1].StopColor.Red * 255.0);
- }
- else
- {
- nRed = ::Color(ColorTransparency, bStart ? rGradient.StartColor : rGradient.EndColor).GetRed();
- }
-
- // drawingML alpha is a percentage on a 0..100000 scale.
- return (255 - nRed) * oox::drawingml::MAX_PERCENT / 255;
-}
-
bool DataLabelsRange::empty() const
{
return maLabels.empty();
@@ -1945,7 +1924,20 @@ void ChartExport::exportSolidFill(const Reference< XPropertySet >& xPropSet)
if (!bNeedGradientFill && 0 != aTransparenceGradient.StartColor)
{
- nAlpha = lcl_getAlphaFromTransparenceGradient(aTransparenceGradient, true);
+ // Our alpha is a gray color value.
+ sal_uInt8 nRed(0);
+
+ if (aTransparenceGradient.ColorStops.getLength() > 0)
+ {
+ nRed = static_cast<sal_uInt8>(aTransparenceGradient.ColorStops[0].StopColor.Red * 255.0);
+ }
+ else
+ {
+ nRed = ::Color(ColorTransparency, aTransparenceGradient.StartColor).GetRed();
+ }
+
+ // drawingML alpha is a percentage on a 0..100000 scale.
+ nAlpha = (255 - nRed) * oox::drawingml::MAX_PERCENT / 255;
}
}
// write XML
@@ -1954,7 +1946,7 @@ void ChartExport::exportSolidFill(const Reference< XPropertySet >& xPropSet)
// no longer create copy/PseudoColorGradient, use new API of
// WriteGradientFill to express fix fill color
mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape, "0");
- WriteGradientFill(nullptr, nFillColor, &aTransparenceGradient, 0);
+ WriteGradientFill(nullptr, nFillColor, &aTransparenceGradient);
mpFS->endElementNS(XML_a, XML_gradFill);
}
else
@@ -2034,7 +2026,7 @@ void ChartExport::exportGradientFill( const Reference< XPropertySet >& xPropSet
uno::Reference< container::XNameAccess > xTransparenceGradient(xFact->createInstance("com.sun.star.drawing.TransparencyGradientTable"), uno::UNO_QUERY);
uno::Any rTransparenceValue = xTransparenceGradient->getByName(sFillTransparenceGradientName);
basegfx::utils::fillGradient2FromAny(aTransparenceGradient, rTransparenceValue);
- WriteGradientFill(&aGradient, 0, &aTransparenceGradient, 0);
+ WriteGradientFill(&aGradient, 0, &aTransparenceGradient);
}
else if (GetProperty(xPropSet, "FillTransparence") )
{
@@ -2042,11 +2034,12 @@ void ChartExport::exportGradientFill( const Reference< XPropertySet >& xPropSet
// WriteGradientFill to express fix transparency
sal_Int32 nTransparency = 0;
mAny >>= nTransparency;
- WriteGradientFill(&aGradient, 0, nullptr, nTransparency);
+ // nTransparency is [0..100]%
+ WriteGradientFill(&aGradient, 0, nullptr, nTransparency * 0.01);
}
else
{
- WriteGradientFill(&aGradient, 0, &aTransparenceGradient, 0);
+ WriteGradientFill(&aGradient, 0, &aTransparenceGradient);
}
mpFS->endElementNS(XML_a, XML_gradFill);
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 77c4c1b02186..ad07308ada62 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -152,28 +152,6 @@ using ::sax_fastparser::FastSerializerHelper;
namespace
{
-/// Extracts start or end alpha information from a transparency gradient.
-sal_Int32 GetAlphaFromTransparenceGradient(const awt::Gradient2& rGradient, bool bStart)
-{
- // Our alpha is a gray color value.
- sal_uInt8 nRed(0);
-
- if (rGradient.ColorStops.getLength() > 0)
- {
- if (bStart)
- nRed = static_cast<sal_uInt8>(rGradient.ColorStops[0].StopColor.Red * 255.0);
- else
- nRed = static_cast<sal_uInt8>(rGradient.ColorStops[rGradient.ColorStops.getLength() - 1].StopColor.Red * 255.0);
- }
- else
- {
- nRed = ::Color(ColorTransparency, bStart ? rGradient.StartColor : rGradient.EndColor).GetRed();
- }
-
- // drawingML alpha is a percentage on a 0..100000 scale.
- return (255 - nRed) * oox::drawingml::MAX_PERCENT / 255;
-}
-
const char* g_aPredefinedClrNames[] = {
"dk1",
"lt1",
@@ -509,7 +487,20 @@ void DrawingML::WriteSolidFill( const Reference< XPropertySet >& rXPropSet )
if (!bNeedGradientFill && 0 != aTransparenceGradient.StartColor)
{
- nAlpha = GetAlphaFromTransparenceGradient(aTransparenceGradient, true);
+ // Our alpha is a gray color value.
+ sal_uInt8 nRed(0);
+
+ if (aTransparenceGradient.ColorStops.getLength() > 0)
+ {
+ nRed = static_cast<sal_uInt8>(aTransparenceGradient.ColorStops[0].StopColor.Red * 255.0);
+ }
+ else
+ {
+ nRed = ::Color(ColorTransparency, aTransparenceGradient.StartColor).GetRed();
+ }
+
+ // drawingML alpha is a percentage on a 0..100000 scale.
+ nAlpha = (255 - nRed) * oox::drawingml::MAX_PERCENT / 255;
}
}
@@ -519,7 +510,7 @@ void DrawingML::WriteSolidFill( const Reference< XPropertySet >& rXPropSet )
// no longer create copy/PseudoColorGradient, use new API of
// WriteGradientFill to express fix fill color
mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape, "0");
- WriteGradientFill(nullptr, nFillColor, &aTransparenceGradient, 0);
+ WriteGradientFill(nullptr, nFillColor, &aTransparenceGradient);
mpFS->endElementNS( XML_a, XML_gradFill );
}
else if ( nFillColor != nOriginalColor )
@@ -600,19 +591,12 @@ bool DrawingML::WriteSchemeColor(OUString const& rPropertyName, const uno::Refer
return true;
}
-void DrawingML::WriteGradientStop2(double fOffset, const basegfx::BColor& rColor, const basegfx::BColor& rAlpha)
+void DrawingML::WriteGradientStop(double fOffset, const basegfx::BColor& rColor, const basegfx::BColor& rAlpha)
{
- mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(static_cast<sal_uInt32>(fOffset * 100000)));
+ mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(basegfx::fround(fOffset * 100000)));
WriteColor(
::Color(rColor),
- static_cast<sal_Int32>((1.0 - rAlpha.luminance()) * oox::drawingml::MAX_PERCENT));
- mpFS->endElementNS( XML_a, XML_gs );
-}
-
-void DrawingML::WriteGradientStop(sal_uInt16 nStop, ::Color nColor, sal_Int32 nAlpha)
-{
- mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(nStop * 1000));
- WriteColor(nColor, nAlpha);
+ basegfx::fround((1.0 - rAlpha.luminance()) * oox::drawingml::MAX_PERCENT));
mpFS->endElementNS( XML_a, XML_gs );
}
@@ -706,7 +690,7 @@ void DrawingML::WriteGradientFill( const Reference< XPropertySet >& rXPropSet )
awt::Gradient2 aTransparenceGradient;
awt::Gradient2* pTransparenceGradient(nullptr);
- sal_Int32 nTransparency(0);
+ double fTransparency(0.0);
OUString sFillTransparenceGradientName;
if (GetProperty(rXPropSet, "FillTransparenceGradientName")
@@ -722,10 +706,13 @@ void DrawingML::WriteGradientFill( const Reference< XPropertySet >& rXPropSet )
{
// no longer create PseudoTransparencyGradient, use new API of
// WriteGradientFill to express fix transparency
+ sal_Int32 nTransparency(0);
mAny >>= nTransparency;
+ // nTransparency is [0..100]%
+ fTransparency = nTransparency * 0.01;
}
- WriteGradientFill(&aGradient, 0, pTransparenceGradient, nTransparency);
+ WriteGradientFill(&aGradient, 0, pTransparenceGradient, fTransparency);
mpFS->endElementNS(XML_a, XML_gradFill);
}
@@ -790,14 +777,14 @@ void DrawingML::WriteGrabBagGradientFill( const Sequence< PropertyValue >& aGrad
}
}
-void DrawingML::WriteGradientFill2(
+void DrawingML::WriteGradientFill(
const awt::Gradient2* pColorGradient, sal_Int32 nFixColor,
- const awt::Gradient2* pTransparenceGradient, sal_Int32 nFixTransparence)
+ const awt::Gradient2* pTransparenceGradient, double fFixTransparence)
{
basegfx::ColorStops aColorStops;
basegfx::ColorStops aAlphaStops;
basegfx::BColor aSingleColor(::Color(ColorTransparency, nFixColor).getBColor());
- basegfx::BColor aSingleAlpha(::Color(ColorTransparency, nFixTransparence).getBColor().luminance());
+ basegfx::BColor aSingleAlpha(fFixTransparence);
awt::Gradient2 aGradient;
if (nullptr != pColorGradient)
@@ -865,10 +852,21 @@ void DrawingML::WriteGradientFill2(
aRevCurrAlpha++;
}
- // add non-mirrored gradients, translated and scaled to [0.5 .. 1.0]
basegfx::ColorStops::const_iterator aCurrColor(aColorStops.begin());
basegfx::ColorStops::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());
@@ -907,7 +905,7 @@ void DrawingML::WriteGradientFill2(
while (aCurrColor != aColorStops.end() && aCurrAlpha != aAlphaStops.end())
{
- WriteGradientStop2(
+ WriteGradientStop(
aCurrColor->getStopOffset(),
aCurrColor->getStopColor(),
aCurrAlpha->getStopColor());
@@ -935,131 +933,6 @@ void DrawingML::WriteGradientFill2(
}
}
-void DrawingML::WriteGradientFill(
- const awt::Gradient2* pColorGradient, sal_Int32 nFixColor,
- const awt::Gradient2* pTransparenceGradient, sal_Int32 nFixTransparence)
-{
- static bool bMCGR(nullptr != std::getenv("MCGR_TEST"));
-
- if (bMCGR)
- {
- WriteGradientFill2(pColorGradient, nFixColor, pTransparenceGradient, nFixTransparence);
- return;
- }
-
- // evtl need a temporary pseudo-color gradient
- awt::Gradient2 aColorGradient;
-
- if (nullptr == pColorGradient && nullptr == pTransparenceGradient)
- {
- // this is an error: *one* gradient has to be given
- return;
- }
-
- if (nullptr == pColorGradient)
- {
- // create complete temporary copy to keep orig export working
- aColorGradient = *pTransparenceGradient;
-
- // change parameters specific for PseudoColorGradient
- aColorGradient.StartIntensity = 100;
- aColorGradient.EndIntensity = 100;
- aColorGradient.StartColor = nFixColor;
- aColorGradient.EndColor = nFixColor;
-
- basegfx::utils::fillColorStopSequenceFromColorStops(
- aColorGradient.ColorStops,
- basegfx::ColorStops {
- basegfx::ColorStop(0.0, ::Color(ColorTransparency, nFixColor).getBColor()) });
-
- pColorGradient = &aColorGradient;
- }
-
- sal_Int32 nStartAlpha(MAX_PERCENT);
- sal_Int32 nEndAlpha(MAX_PERCENT);
-
- if (nullptr == pTransparenceGradient)
- {
- nStartAlpha = nEndAlpha = (MAX_PERCENT - (PER_PERCENT * nFixTransparence));
- }
- else
- {
- nStartAlpha = GetAlphaFromTransparenceGradient(*pTransparenceGradient, true);
- nEndAlpha = GetAlphaFromTransparenceGradient(*pTransparenceGradient, false);
- }
-
- switch( pColorGradient->Style )
- {
- default:
- case awt::GradientStyle_LINEAR:
- {
- mpFS->startElementNS(XML_a, XML_gsLst);
- WriteGradientStop(pColorGradient->Border, ColorWithIntensity(pColorGradient->StartColor, pColorGradient->StartIntensity),
- nStartAlpha);
- WriteGradientStop(100, ColorWithIntensity(pColorGradient->EndColor, pColorGradient->EndIntensity),
- nEndAlpha);
- mpFS->endElementNS( XML_a, XML_gsLst );
- mpFS->singleElementNS(
- XML_a, XML_lin, XML_ang,
- OString::number(((3600 - pColorGradient->Angle + 900) * 6000) % 21600000));
- break;
- }
-
- case awt::GradientStyle_AXIAL:
- {
- mpFS->startElementNS(XML_a, XML_gsLst);
- WriteGradientStop(0, ColorWithIntensity(pColorGradient->EndColor, pColorGradient->EndIntensity),
- nEndAlpha);
- if (pColorGradient->Border > 0 && pColorGradient->Border < 100)
- {
- WriteGradientStop(pColorGradient->Border/2,
- ColorWithIntensity(pColorGradient->EndColor, pColorGradient->EndIntensity),
- nEndAlpha);
- }
- WriteGradientStop(50, ColorWithIntensity(pColorGradient->StartColor, pColorGradient->StartIntensity),
- nStartAlpha);
- if (pColorGradient->Border > 0 && pColorGradient->Border < 100)
- {
- WriteGradientStop(100 - pColorGradient->Border/2,
- ColorWithIntensity(pColorGradient->EndColor, pColorGradient->EndIntensity),
- nEndAlpha);
- }
- WriteGradientStop(100, ColorWithIntensity(pColorGradient->EndColor, pColorGradient->EndIntensity),
- nEndAlpha);
- mpFS->endElementNS(XML_a, XML_gsLst);
- mpFS->singleElementNS(
- XML_a, XML_lin, XML_ang,
- OString::number(((3600 - pColorGradient->Angle + 900) * 6000) % 21600000));
- break;
- }
-
- case awt::GradientStyle_RADIAL:
- case awt::GradientStyle_ELLIPTICAL:
- case awt::GradientStyle_RECT:
- case awt::GradientStyle_SQUARE:
- {
- mpFS->startElementNS(XML_a, XML_gsLst);
- WriteGradientStop(0, ColorWithIntensity(pColorGradient->EndColor, pColorGradient->EndIntensity),
- nEndAlpha);
- if (pColorGradient->Border > 0 && pColorGradient->Border < 100)
- {
- // Map border to an additional gradient stop, which has the
- // same color as the final stop.
- WriteGradientStop(100 - pColorGradient->Border,
- ColorWithIntensity(pColorGradient->StartColor, pColorGradient->StartIntensity),
- nStartAlpha);
- }
- WriteGradientStop(100,
- ColorWithIntensity(pColorGradient->StartColor, pColorGradient->StartIntensity),
- nStartAlpha);
- mpFS->endElementNS(XML_a, XML_gsLst);
-
- WriteGradientPath(*pColorGradient, mpFS, pColorGradient->Style == awt::GradientStyle_RADIAL || pColorGradient->Style == awt::GradientStyle_ELLIPTICAL);
- break;
- }
- }
-}
-
void DrawingML::WriteLineArrow( const Reference< XPropertySet >& rXPropSet, bool bLineStart )
{
ESCHER_LineEnd eLineEnd;