Kaydet (Commit) 30e934df authored tarafından Miklos Vajna's avatar Miklos Vajna Kaydeden (comit) Jan Holesovsky

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 82365563)

Conflicts:
	oox/source/export/drawingml.cxx
	sd/qa/unit/import-tests.cxx

Change-Id: I88db7d579da7327e5e06b736a75a6892b338dd73
Reviewed-on: https://gerrit.libreoffice.org/67395Reviewed-by: 's avatarJan Holesovsky <kendy@collabora.com>
Tested-by: 's avatarJan Holesovsky <kendy@collabora.com>
üst f4999d0e
......@@ -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:
......
......@@ -102,6 +102,7 @@ public:
void testTdf111884();
void testTdf112633();
void testCustomXml();
void testTdf94238();
CPPUNIT_TEST_SUITE(SdOOXMLExportTest1);
......@@ -132,6 +133,7 @@ public:
CPPUNIT_TEST(testTdf111884);
CPPUNIT_TEST(testTdf112633);
CPPUNIT_TEST(testCustomXml);
CPPUNIT_TEST(testTdf94238);
CPPUNIT_TEST_SUITE_END();
......@@ -854,6 +856,38 @@ void SdOOXMLExportTest1::testCustomXml()
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_PLUGIN_IMPLEMENT();
......
......@@ -179,7 +179,6 @@ public:
void testTdf119015();
void testTdf120028();
void testTdf120028b();
void testTdf94238();
CPPUNIT_TEST_SUITE(SdImportTest);
......@@ -258,7 +257,6 @@ public:
CPPUNIT_TEST(testTdf119015);
CPPUNIT_TEST(testTdf120028);
CPPUNIT_TEST(testTdf120028b);
CPPUNIT_TEST(testTdf94238);
CPPUNIT_TEST_SUITE_END();
};
......@@ -2518,37 +2516,6 @@ void SdImportTest::testTdf120028b()
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);
xDocShRef->DoClose();
}
CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest);
CPPUNIT_PLUGIN_IMPLEMENT();
......
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