Kaydet (Commit) 82365563 authored tarafından Miklos Vajna's avatar Miklos Vajna

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.

Change-Id: I88db7d579da7327e5e06b736a75a6892b338dd73
Reviewed-on: https://gerrit.libreoffice.org/67369Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
üst 0a203393
...@@ -140,7 +140,32 @@ static css::uno::Any getLineDash( const css::uno::Reference<css::frame::XModel>& ...@@ -140,7 +140,32 @@ static css::uno::Any getLineDash( const css::uno::Reference<css::frame::XModel>&
return css::uno::Any(); return css::uno::Any();
} }
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 // not thread safe
int DrawingML::mnImageCounter = 1; int DrawingML::mnImageCounter = 1;
...@@ -459,9 +484,17 @@ void DrawingML::WriteGrabBagGradientFill( const Sequence< PropertyValue >& aGrad ...@@ -459,9 +484,17 @@ void DrawingML::WriteGrabBagGradientFill( const Sequence< PropertyValue >& aGrad
} }
mpFS->endElementNS( XML_a, XML_gsLst ); mpFS->endElementNS( XML_a, XML_gsLst );
mpFS->singleElementNS( XML_a, XML_lin, switch (rGradient.Style)
XML_ang, I32S( ( ( ( 3600 - rGradient.Angle + 900 ) * 6000 ) % 21600000 ) ), {
FSEND ); 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 ) void DrawingML::WriteGradientFill( awt::Gradient rGradient )
...@@ -490,10 +523,26 @@ void DrawingML::WriteGradientFill( awt::Gradient rGradient ) ...@@ -490,10 +523,26 @@ void DrawingML::WriteGradientFill( awt::Gradient rGradient )
FSEND ); FSEND );
break; 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 /* I don't see how to apply transformation to gradients, so
* elliptical will end as radial and square as * elliptical will end as radial and square as
* rectangular. also position offsets are not applied */ * rectangular. also position offsets are not applied */
case awt::GradientStyle_RADIAL:
case awt::GradientStyle_ELLIPTICAL: case awt::GradientStyle_ELLIPTICAL:
case awt::GradientStyle_RECT: case awt::GradientStyle_RECT:
case awt::GradientStyle_SQUARE: case awt::GradientStyle_SQUARE:
......
...@@ -101,6 +101,7 @@ public: ...@@ -101,6 +101,7 @@ public:
void testTdf111884(); void testTdf111884();
void testTdf112633(); void testTdf112633();
void testCustomXml(); void testCustomXml();
void testTdf94238();
CPPUNIT_TEST_SUITE(SdOOXMLExportTest1); CPPUNIT_TEST_SUITE(SdOOXMLExportTest1);
...@@ -131,6 +132,7 @@ public: ...@@ -131,6 +132,7 @@ public:
CPPUNIT_TEST(testTdf111884); CPPUNIT_TEST(testTdf111884);
CPPUNIT_TEST(testTdf112633); CPPUNIT_TEST(testTdf112633);
CPPUNIT_TEST(testCustomXml); CPPUNIT_TEST(testCustomXml);
CPPUNIT_TEST(testTdf94238);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
...@@ -846,6 +848,38 @@ void SdOOXMLExportTest1::testCustomXml() ...@@ -846,6 +848,38 @@ void SdOOXMLExportTest1::testCustomXml()
CPPUNIT_ASSERT(pStream); CPPUNIT_ASSERT(pStream);
} }
void SdOOXMLExportTest1::testTdf94238()
{
// Load document and export it to a temporary file.
::sd::DrawDocShellRef xDocShRef
= loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf94238.pptx"), PPTX);
utl::TempFile tempFile;
xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(),
uno::UNO_QUERY);
CPPUNIT_ASSERT(xDoc.is());
uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
CPPUNIT_ASSERT(xPage.is());
uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
CPPUNIT_ASSERT(xShape.is());
awt::Gradient aGradient;
CPPUNIT_ASSERT(xShape->getPropertyValue("FillGradient") >>= aGradient);
// Without the accompanying fix in place, this test would have failed with
// the following details:
// - aGradient.Style was awt::GradientStyle_ELLIPTICAL
// - aGradient.YOffset was 70
// - aGradient.Border was 0
CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_RADIAL, aGradient.Style);
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(100), aGradient.YOffset);
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(39), aGradient.Border);
xDocShRef->DoClose();
}
CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest1); CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest1);
CPPUNIT_PLUGIN_IMPLEMENT(); CPPUNIT_PLUGIN_IMPLEMENT();
......
...@@ -192,7 +192,6 @@ public: ...@@ -192,7 +192,6 @@ public:
void testTdf119015(); void testTdf119015();
void testTdf120028(); void testTdf120028();
void testTdf120028b(); void testTdf120028b();
void testTdf94238();
void testTdf44223(); void testTdf44223();
CPPUNIT_TEST_SUITE(SdImportTest); CPPUNIT_TEST_SUITE(SdImportTest);
...@@ -277,7 +276,6 @@ public: ...@@ -277,7 +276,6 @@ public:
CPPUNIT_TEST(testTdf119015); CPPUNIT_TEST(testTdf119015);
CPPUNIT_TEST(testTdf120028); CPPUNIT_TEST(testTdf120028);
CPPUNIT_TEST(testTdf120028b); CPPUNIT_TEST(testTdf120028b);
CPPUNIT_TEST(testTdf94238);
CPPUNIT_TEST(testTdf44223); CPPUNIT_TEST(testTdf44223);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
...@@ -2598,35 +2596,6 @@ void SdImportTest::testTdf120028b() ...@@ -2598,35 +2596,6 @@ void SdImportTest::testTdf120028b()
xDocShRef->DoClose(); xDocShRef->DoClose();
} }
void SdImportTest::testTdf94238()
{
// Assert how the gradient fill of the only shape in the document is
// imported.
::sd::DrawDocShellRef xDocShRef
= loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf94238.pptx"), PPTX);
uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(),
uno::UNO_QUERY);
CPPUNIT_ASSERT(xDoc.is());
uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
CPPUNIT_ASSERT(xPage.is());
uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
CPPUNIT_ASSERT(xShape.is());
awt::Gradient aGradient;
CPPUNIT_ASSERT(xShape->getPropertyValue("FillGradient") >>= aGradient);
// Without the accompanying fix in place, this test would have failed with
// the following details:
// - aGradient.Style was awt::GradientStyle_ELLIPTICAL
// - aGradient.YOffset was 70
// - aGradient.Border was 0
CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_RADIAL, aGradient.Style);
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(100), aGradient.YOffset);
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(39), aGradient.Border);
}
void SdImportTest::testTdf44223() void SdImportTest::testTdf44223()
{ {
::sd::DrawDocShellRef xDocShRef ::sd::DrawDocShellRef xDocShRef
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment