diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-10-06 15:27:24 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-10-06 16:12:07 +0200 |
commit | e7ca10a35fd665722c67eea85e15f71c11c66248 (patch) | |
tree | 91d7a759e47b3f937ded1357605b428e376a78dc /filter | |
parent | 22c66999008aec900c49e5c6caf9a14d3e4e2969 (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.
Change-Id: Ie21bffce9d09194159e460fb28ab23fbefd52102
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141014
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'filter')
-rw-r--r-- | filter/qa/unit/svg.cxx | 39 | ||||
-rw-r--r-- | filter/source/svg/svgwriter.cxx | 6 |
2 files changed, 45 insertions, 0 deletions
diff --git a/filter/qa/unit/svg.cxx b/filter/qa/unit/svg.cxx index 8cb696efa170..5506d1601cda 100644 --- a/filter/qa/unit/svg.cxx +++ b/filter/qa/unit/svg.cxx @@ -18,6 +18,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> @@ -251,6 +255,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 9f889924cfb6..fb0193e15418 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -1624,6 +1624,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; } |