From 80550ade305b9e68c6281a258d162bc2c413713a Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 20 Sep 2022 09:10:25 +0200 Subject: tdf#150990 ODT export: fix zero layout size of scale/scale images The bugdoc has a broken image where both axis are set to a relative size of 255%, which means "keep aspect", and the expectation is that only one axis uses this to match the size of the other axis. The problem was that commit b578fa08a25a83abccad2386e12b707586fffb26 (ODT export: fix fallback svg:width/height for text frames with relative sizes, 2022-03-16) assumed that only one axis uses "scale", so we always get a non-zero layout size. Fix the problem by only using the layout size when exactly one axis uses the "scale" percentage, which is the expected the case. This way we just keep the aspect ratio of broken documents, then the UI will in practice ignore the scale request of the width. Change-Id: I2dbd6bb92f912f6185422fd301b99b284a66ef74 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140218 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- xmloff/qa/unit/text.cxx | 37 +++++++++++++++++++++++++++++++++++++ xmloff/source/text/txtparae.cxx | 12 ++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) (limited to 'xmloff') diff --git a/xmloff/qa/unit/text.cxx b/xmloff/qa/unit/text.cxx index 53f1de102fc3..8ad3ea6f941b 100644 --- a/xmloff/qa/unit/text.cxx +++ b/xmloff/qa/unit/text.cxx @@ -385,6 +385,43 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testRelativeWidth) assertXPath(pXmlDoc, "//draw:frame", "width", "3.1492in"); } +CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testScaleWidthAndHeight) +{ + // Given a broken document where both IsSyncHeightToWidth and IsSyncWidthToHeight are set to + // true: + getComponent() = loadFromDesktop("private:factory/swriter"); + uno::Reference xMSF(getComponent(), uno::UNO_QUERY); + uno::Reference xTextDocument(getComponent(), uno::UNO_QUERY); + uno::Reference xTextFrame( + xMSF->createInstance("com.sun.star.text.TextFrame"), uno::UNO_QUERY); + uno::Reference xTextFrameProps(xTextFrame, uno::UNO_QUERY); + xTextFrameProps->setPropertyValue("Width", uno::Any(static_cast(2000))); + xTextFrameProps->setPropertyValue("Height", uno::Any(static_cast(1000))); + xTextFrameProps->setPropertyValue("IsSyncHeightToWidth", uno::Any(true)); + xTextFrameProps->setPropertyValue("IsSyncWidthToHeight", uno::Any(true)); + uno::Reference xText = xTextDocument->getText(); + uno::Reference xCursor = xText->createTextCursor(); + xText->insertTextContent(xCursor, xTextFrame, /*bAbsorb=*/false); + + // When exporting to ODT: + uno::Reference xStorable(getComponent(), uno::UNO_QUERY); + uno::Sequence aStoreProps = comphelper::InitPropertySequence({ + { "FilterName", uno::Any(OUString("writer8")) }, + }); + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + xStorable->storeToURL(aTempFile.GetURL(), aStoreProps); + + // Then make sure that we still export a non-zero size: + std::unique_ptr pStream = parseExportStream(aTempFile, "content.xml"); + xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get()); + // Without the accompanying fix in place, this failed with: + // - Expected: 0.7874in + // - Actual : 0in + // i.e. the exported size was 0, not 2000 mm100 in inches. + assertXPath(pXmlDoc, "//draw:frame", "width", "0.7874in"); +} + CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testContentControlExport) { // Given a document with a content control around one or more text portions: diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx index ec0457feb755..fdb3de666389 100644 --- a/xmloff/source/text/txtparae.cxx +++ b/xmloff/source/text/txtparae.cxx @@ -2866,6 +2866,14 @@ XMLShapeExportFlags XMLTextParagraphExport::addTextFrameAttributes( rPropSet->getPropertyValue("LayoutSize") >>= aLayoutSize; } + bool bUseLayoutSize = true; + if (bSyncWidth && bSyncHeight) + { + // This is broken, width depends on height and height depends on width. Don't use the + // invalid layout size we got. + bUseLayoutSize = false; + } + // svg:width sal_Int16 nWidthType = SizeType::FIX; if( xPropSetInfo->hasPropertyByName( gsWidthType ) ) @@ -2891,7 +2899,7 @@ XMLShapeExportFlags XMLTextParagraphExport::addTextFrameAttributes( } else { - if (nRelWidth > 0 || bSyncWidth) + if ((nRelWidth > 0 || bSyncWidth) && bUseLayoutSize) { // Relative width: write the layout size for the fallback width. sValue.setLength(0); @@ -2947,7 +2955,7 @@ XMLShapeExportFlags XMLTextParagraphExport::addTextFrameAttributes( } else { - if (nRelHeight > 0 || bSyncHeight) + if ((nRelHeight > 0 || bSyncHeight) && bUseLayoutSize) { // Relative height: write the layout size for the fallback height. sValue.setLength(0); -- cgit