summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2022-04-23 21:52:29 +0200
committerAndras Timar <andras.timar@collabora.com>2022-04-27 13:20:00 +0200
commite9786a1439db437cc378f426c7cb496db20959fd (patch)
tree22eefee62af224b77fc2636871d99d3b360cffaa /oox
parentd00bcd99a01e09259afa3c2ef17424aa2282a48b (diff)
Do not start a:path with lnTo in export to OOXML
This is a follow up to commit 2029b2f6dd0109c5892e5ac5640022b31fe42fd2 The commands A, W, T or L of a draw:enhanced-path draw a line from current point to start of the arc or end of line, respectivly. If there is no current point the path is faulty and behavior is not defined in ODF. LibreOffice is tolerant and makes a move to the start point of the arc or to the end point of the line. With this patch we do the same now in export to OOXML, so the user gets the same shape geometry as in LO. If a path starts with lnTo, MS Office will show nothing. I wouldn't care about user-created faulty paths, but LO produces such faulty path when an EllipseRibbon shape from binary MS Office is imported. Even when that will be fixed, we need the fix here, because the faulty path had been written to document markup and will be used when such document is opened. Change-Id: Ic52ec3bc78231b26efb592ddadee2e3042fdc065 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133349 Tested-by: Jenkins Reviewed-by: Regina Henschel <rb.henschel@t-online.de> Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133370
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 e104b4effdd7..26d1a0e973bb 100644
--- a/oox/qa/unit/export.cxx
+++ b/oox/qa/unit/export.cxx
@@ -529,6 +529,26 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf147978_subpath)
assertXPath(pXmlDoc, "//a:pathLst/a:path[4]", "w", "80");
assertXPath(pXmlDoc, "//a:pathLst/a:path[4]", "h", "80");
}
+
+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 311669bd5cbe..c2bdf39042a4 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -3997,10 +3997,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;
@@ -4063,7 +4074,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)),
@@ -4126,7 +4138,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)),