summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
Diffstat (limited to 'oox')
-rw-r--r--oox/qa/unit/data/FaultyPathStart.odpbin0 -> 14582 bytes
-rw-r--r--oox/qa/unit/export.cxx20
-rw-r--r--oox/source/export/drawingml.cxx25
3 files changed, 39 insertions, 6 deletions
diff --git a/oox/qa/unit/data/FaultyPathStart.odp b/oox/qa/unit/data/FaultyPathStart.odp
new file mode 100644
index 000000000000..219795ffa58b
--- /dev/null
+++ b/oox/qa/unit/data/FaultyPathStart.odp
Binary files differ
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)),