diff options
Diffstat (limited to 'oox')
-rw-r--r-- | oox/qa/unit/data/FaultyPathStart.odp | bin | 0 -> 14582 bytes | |||
-rw-r--r-- | oox/qa/unit/export.cxx | 20 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 25 |
3 files changed, 39 insertions, 6 deletions
diff --git a/oox/qa/unit/data/FaultyPathStart.odp b/oox/qa/unit/data/FaultyPathStart.odp Binary files differnew file mode 100644 index 000000000000..219795ffa58b --- /dev/null +++ b/oox/qa/unit/data/FaultyPathStart.odp diff --git a/oox/qa/unit/export.cxx b/oox/qa/unit/export.cxx index b4eebc537250..7a1bda7cb5bd 100644 --- a/oox/qa/unit/export.cxx +++ b/oox/qa/unit/export.cxx @@ -632,6 +632,26 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf109169_OctagonBevel) assertXPath(pXmlDoc, "//a:pathLst/a:path[5]", "fill", "lightenLess"); assertXPath(pXmlDoc, "//a:pathLst/a:path[6]", "fill", "lighten"); } + +CPPUNIT_TEST_FIXTURE(Test, testFaultyPathCommandsAWT) +{ + // The odp file contains shapes whose path starts with command A, W, T or L. That is a faulty + // path. LO is tolerant and renders it so that is makes a moveTo to the start point of the arc or + // the end of the line respectively. Export to OOXML does the same now and writes a moveTo + // instead of the normally used lnTo. If a lnTo is written, MS Office shows nothing of the shape. + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "FaultyPathStart.odp"; + + loadAndSave(aURL, "Impress Office Open XML"); + + // Verify the markup: + std::unique_ptr<SvStream> pStream = parseExportStream(getTempFile(), "ppt/slides/slide1.xml"); + xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get()); + // First child of a:path should be a moveTo in all four shapes. + assertXPath(pXmlDoc, "//p:spTree/p:sp[1]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo"); + assertXPath(pXmlDoc, "//p:spTree/p:sp[2]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo"); + assertXPath(pXmlDoc, "//p:spTree/p:sp[3]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo"); + assertXPath(pXmlDoc, "//p:spTree/p:sp[4]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo"); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 327b567c4c40..78eac3d00f60 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -4218,10 +4218,21 @@ bool DrawingML::WriteCustomGeometrySegment( { if (rnPairIndex >= rPairs.getLength()) return false; - - mpFS->startElementNS(XML_a, XML_lnTo); - WriteCustomGeometryPoint(rPairs[rnPairIndex], rCustomShape2d); - mpFS->endElementNS(XML_a, XML_lnTo); + // LINETO without valid current point is a faulty path. LO is tolerant and makes a + // moveTo instead. Do the same on export. MS OFFICE requires a current point for lnTo, + // otherwise it shows nothing of the shape. + if (rbCurrentValid) + { + mpFS->startElementNS(XML_a, XML_lnTo); + WriteCustomGeometryPoint(rPairs[rnPairIndex], rCustomShape2d); + mpFS->endElementNS(XML_a, XML_lnTo); + } + else + { + mpFS->startElementNS(XML_a, XML_moveTo); + WriteCustomGeometryPoint(rPairs[rnPairIndex], rCustomShape2d); + mpFS->endElementNS(XML_a, XML_moveTo); + } rCustomShape2d.GetParameter(rfCurrentX, rPairs[rnPairIndex].First, false, false); rCustomShape2d.GetParameter(rfCurrentY, rPairs[rnPairIndex].Second, false, false); rbCurrentValid = true; @@ -4284,7 +4295,8 @@ bool DrawingML::WriteCustomGeometrySegment( getEllipsePointFromViewAngle(fSx, fSy, fWR, fHR, fCx, fCy, fStartAngle); // write markup for going to start point - if (eCommand == ANGLEELLIPSETO) + // lnTo requires a valid current point + if (eCommand == ANGLEELLIPSETO && rbCurrentValid) { mpFS->startElementNS(XML_a, XML_lnTo); mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fSx)), @@ -4347,7 +4359,8 @@ bool DrawingML::WriteCustomGeometrySegment( getEllipsePointAndAngleFromRayPoint(fStartAngle, fPx, fPy, fWR, fHR, fCx, fCy, fX3, fY3); // markup for going to start point - if (eCommand == ARCTO || eCommand == CLOCKWISEARCTO) + // lnTo requires a valid current point. + if ((eCommand == ARCTO || eCommand == CLOCKWISEARCTO) && rbCurrentValid) { mpFS->startElementNS(XML_a, XML_lnTo); mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fPx)), |