summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-10-06 15:27:24 +0200
committerAndras Timar <andras.timar@collabora.com>2022-10-10 14:04:06 +0200
commit074c5b90f71e589d3e531f8606ac0e0c6ff12af2 (patch)
treefbc473b092d691c30a20eaa5af6eeeeef4e8cb33
parent02624d2bff8b5ae67d5861f6a987aacdfd82dd41 (diff)
SVG export: don't loose tab portions
Impress slides are exported to SVG via a metafile. In case shape text has a string like "A\tB", that was exported as "AB", loosing the tab character. The relevant shape is exported as a metafile, with two text array metafile actions (one for "A", one for "B") and the tab needs no explicit action as both "A" and "B" has an explicit position. The SVG contained no explicit position for "B", so the tab was lost visually. Fix the problem by detecting when the doc model has a "\t" without a matching metafile action and emitting the explicit position in that case. An alternative would be to use implWriteTextPortion() to write a <tspan> for the tab, but that doesn't guarantee that the width of the tab in the SVG is the same as in Impress. (cherry picked from commit e7ca10a35fd665722c67eea85e15f71c11c66248) Change-Id: Ie21bffce9d09194159e460fb28ab23fbefd52102 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141026 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Marco Cecchetti <marco.cecchetti@collabora.com> (cherry picked from commit cd04f3973c33e081fb0feb176e7c5e4f11759d77) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141065 Reviewed-by: Andras Timar <andras.timar@collabora.com>
-rw-r--r--filter/qa/unit/svg.cxx39
-rw-r--r--filter/source/svg/svgwriter.cxx6
2 files changed, 45 insertions, 0 deletions
diff --git a/filter/qa/unit/svg.cxx b/filter/qa/unit/svg.cxx
index 31c8076637a8..4a2f5df57c80 100644
--- a/filter/qa/unit/svg.cxx
+++ b/filter/qa/unit/svg.cxx
@@ -14,6 +14,10 @@
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
#include <unotools/streamwrap.hxx>
#include <unotools/mediadescriptor.hxx>
#include <tools/stream.hxx>
@@ -248,6 +252,41 @@ CPPUNIT_TEST_FIXTURE(SvgFilterTest, attributeRedefinedTest)
assertXPath(pXmlDoc, xPath + "[4]", "id", "id7");
}
+CPPUNIT_TEST_FIXTURE(SvgFilterTest, testTab)
+{
+ // Given a shape with "A\tB" text:
+ getComponent() = loadFromDesktop("private:factory/simpress",
+ "com.sun.star.presentation.PresentationDocument");
+ uno::Reference<lang::XMultiServiceFactory> xFactory(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xShape(
+ xFactory->createInstance("com.sun.star.drawing.TextShape"), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XShapes> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY);
+ xDrawPage->add(xShape);
+ xShape->setSize(awt::Size(10000, 10000));
+ uno::Reference<text::XTextRange> xShapeText(xShape, uno::UNO_QUERY);
+ xShapeText->setString("A\tB");
+
+ // When exporting that document to SVG:
+ uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY_THROW);
+ SvMemoryStream aStream;
+ uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aStream);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
+ aMediaDescriptor["OutputStream"] <<= xOut;
+ xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
+
+ // Then make sure the the tab is not lost:
+ aStream.Seek(STREAM_SEEK_TO_BEGIN);
+ xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 1
+ // i.e. the 2nd text portion was not positioned, which looked as if the tab is lost.
+ assertXPath(pXmlDoc, "//svg:g[@class='TextShape']//svg:tspan[@class='TextPosition']", 2);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index 4da018fa8f9b..71286a082c42 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -1636,6 +1636,12 @@ void SVGTextWriter::writeTextPortion( const Point& rPos,
continue;
if( sContent == "\n" )
mbLineBreak = true;
+ else if (sContent == "\t")
+ {
+ // Need to emit position for the next text portion after a tab, otherwise the tab
+ // would appear as if it has 0 width.
+ mbPositioningNeeded = true;
+ }
if( sContent.match( rText, nStartPos ) )
bNotSync = false;
}