sw/qa/extras/layout/data/tdf128959.docx |binary sw/qa/extras/layout/layout.cxx | 23 +++++++++ sw/qa/extras/ooxmlexport/data/tdf130494.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport11.cxx | 13 +++++ sw/qa/extras/ooxmlimport/data/wrap-poly-crop.docx |binary sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 53 +++++++++++++++++---- sw/source/core/text/xmldump.cxx | 19 ++++++- sw/source/filter/ww8/docxsdrexport.cxx | 3 - sw/source/filter/ww8/rtfattributeoutput.cxx | 4 - sw/source/filter/ww8/writerhelper.cxx | 24 +++++++++ sw/source/filter/ww8/writerhelper.hxx | 2 sw/source/filter/ww8/wrtw8esh.cxx | 2 writerfilter/source/dmapper/DomainMapper_Impl.cxx | 29 +++++++++-- writerfilter/source/dmapper/GraphicImport.cxx | 11 ++++ writerfilter/source/dmapper/WrapPolygonHandler.cxx | 21 +++++++- writerfilter/source/dmapper/WrapPolygonHandler.hxx | 7 ++ 16 files changed, 186 insertions(+), 25 deletions(-)
New commits: commit 2e8fde3485f07d48d61b6040961c394e2121720b Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu May 14 18:02:23 2020 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon May 18 17:00:06 2020 +0200 DOCX export: fix interaction between the crop and the wrap polygon of image If the wrap polygon is influenced by crop at import time, we need to do the opposite at export time. Do this for RTF and DOCX, where there is matching import code in writerfilter/, leave DOC alone for now. Test this by changing testFdo76803 into an export test, then seeing how the first point's Y position fails and fixing up the exporter, so we get back the old good value. Conflicts: sw/source/filter/ww8/docxsdrexport.cxx writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx (cherry picked from commit c68b458514b35cae70c9a6630e06f46a867aa3b9) Change-Id: Ieef18aad3c76f7945c7348201b07bcb27a4cd48d diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 513a5d64a7d4..fdcd8af60d0d 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -882,8 +882,13 @@ DECLARE_OOXMLIMPORT_TEST(testFdo75722dml, "fdo75722-dml.docx") CPPUNIT_ASSERT_EQUAL(sal_Int64(3128), nRot); } -DECLARE_OOXMLIMPORT_TEST(testFdo76803, "fdo76803.docx") +DECLARE_OOXMLEXPORT_TEST(testFdo76803, "fdo76803.docx") { + if (!mbExported) + { + return; + } + // The ContourPolyPolygon was wrong uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY); @@ -898,16 +903,20 @@ DECLARE_OOXMLIMPORT_TEST(testFdo76803, "fdo76803.docx") CPPUNIT_ASSERT_EQUAL(sal_uInt32(4), aPolygon.count()); - CPPUNIT_ASSERT_EQUAL(double(-162), aPolygon.getB2DPoint(0).getX()); + CPPUNIT_ASSERT_EQUAL(double(-149), aPolygon.getB2DPoint(0).getX()); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: -35 + // - Actual : -67 + // i.e. the cropping did not influence the wrap polygon during export. CPPUNIT_ASSERT_EQUAL(double(-35), aPolygon.getB2DPoint(0).getY()); - CPPUNIT_ASSERT_EQUAL(double(-162), aPolygon.getB2DPoint(1).getX()); - CPPUNIT_ASSERT_EQUAL(double(3510), aPolygon.getB2DPoint(1).getY()); + CPPUNIT_ASSERT_EQUAL(double(-149), aPolygon.getB2DPoint(1).getX()); + CPPUNIT_ASSERT_EQUAL(double(3511), aPolygon.getB2DPoint(1).getY()); - CPPUNIT_ASSERT_EQUAL(double(16892), aPolygon.getB2DPoint(2).getX()); - CPPUNIT_ASSERT_EQUAL(double(3510), aPolygon.getB2DPoint(2).getY()); + CPPUNIT_ASSERT_EQUAL(double(16889), aPolygon.getB2DPoint(2).getX()); + CPPUNIT_ASSERT_EQUAL(double(3511), aPolygon.getB2DPoint(2).getY()); - CPPUNIT_ASSERT_EQUAL(double(16892), aPolygon.getB2DPoint(3).getX()); + CPPUNIT_ASSERT_EQUAL(double(16889), aPolygon.getB2DPoint(3).getX()); CPPUNIT_ASSERT_EQUAL(double(-35), aPolygon.getB2DPoint(3).getY()); } @@ -1624,13 +1633,14 @@ DECLARE_OOXMLIMPORT_TEST(testWrapPolyCrop, "wrap-poly-crop.docx") // 10582, the lower 33% of the graphic is cropped, and the wrap polygon covers the middle third // of the area vertically. Which means 10582*2/3 = 7054.67 is the cropped height, and the top of // the middle third is 2351.55. + // Then there is a 15 twips shift from the origo, so it's 2351.55 + 26.46 = 2378.01 in mm100. // // Without the accompanying fix in place, this test would have failed with: - // - Expected: 2361 + // - Expected: 2368 // - Actual : 3542 // i.e. the wrap polygon covered a larger-than-correct area, which end the end means 3 lines // were wrapping around the image, not only 2 as Word does it. - CPPUNIT_ASSERT_EQUAL(2361., aPolygon.getB2DPoint(0).getY()); + CPPUNIT_ASSERT_EQUAL(2368., aPolygon.getB2DPoint(0).getY()); } DECLARE_OOXMLIMPORT_TEST(testTdf117843, "tdf117843.docx") diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index 459811f0a56b..0a690a9ba00f 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -700,7 +700,8 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, cons m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_wrapPolygon, XML_edited, "0", FSEND); - tools::Polygon aPoly = sw::util::CorrectWordWrapPolygonForExport(*pPolyPoly, pNd); + tools::Polygon aPoly = sw::util::CorrectWordWrapPolygonForExport( + *pPolyPoly, pNd, /*bCorrectCrop=*/true); for (sal_uInt16 i = 0; i < aPoly.GetSize(); ++i) m_pImpl->m_pSerializer->singleElementNS(XML_wp, (i == 0 ? XML_start : XML_lineTo), XML_x, OString::number(aPoly[i].X()), diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 93776963dadb..b1036b59d6b3 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -4131,8 +4131,8 @@ void RtfAttributeOutput::FlyFrameGraphic(const SwFlyFrameFormat* pFlyFrameFormat const tools::PolyPolygon* pPolyPoly = pNd->HasContour(); if (pPolyPoly && pPolyPoly->Count()) { - tools::Polygon aPoly - = sw::util::CorrectWordWrapPolygonForExport(*pPolyPoly, pNd); + tools::Polygon aPoly = sw::util::CorrectWordWrapPolygonForExport( + *pPolyPoly, pNd, /*bCorrectCrop=*/true); OStringBuffer aVerticies; for (sal_uInt16 i = 0; i < aPoly.GetSize(); ++i) aVerticies.append(";(") diff --git a/sw/source/filter/ww8/writerhelper.cxx b/sw/source/filter/ww8/writerhelper.cxx index bf841d6d977a..4724194c6c8c 100644 --- a/sw/source/filter/ww8/writerhelper.cxx +++ b/sw/source/filter/ww8/writerhelper.cxx @@ -55,6 +55,7 @@ #include <IDocumentStylePoolAccess.hxx> #include <IDocumentMarkAccess.hxx> #include <IMark.hxx> +#include <grfatr.hxx> using namespace com::sun::star; @@ -667,10 +668,31 @@ namespace sw } } - tools::Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon& rPolyPoly, const SwNoTextNode* pNd) + tools::Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon& rPolyPoly, const SwNoTextNode* pNd, bool bCorrectCrop) { tools::Polygon aPoly(PolygonFromPolyPolygon(rPolyPoly)); const Size &rOrigSize = pNd->GetGraphic().GetPrefSize(); + + const SwAttrSet* pAttrSet = pNd->GetpSwAttrSet(); + if (bCorrectCrop && pAttrSet) + { + if (pAttrSet->HasItem(RES_GRFATR_CROPGRF)) + { + // Word's wrap polygon deals with a canvas which has the size of the already + // cropped graphic, do the opposite of correctCrop() in writerfilter/. + const SwCropGrf& rCrop = pAttrSet->GetCropGrf(); + sal_Int32 nCropLeft = convertTwipToMm100(rCrop.GetLeft()); + sal_Int32 nCropRight = convertTwipToMm100(rCrop.GetRight()); + sal_Int32 nCropTop = convertTwipToMm100(rCrop.GetTop()); + sal_Int32 nCropBottom = convertTwipToMm100(rCrop.GetBottom()); + aPoly.Move(-nCropLeft, -nCropTop); + + Fraction aScaleX(rOrigSize.getWidth(), rOrigSize.getWidth() - nCropLeft - nCropRight); + Fraction aScaleY(rOrigSize.getHeight(), rOrigSize.getHeight() - nCropTop - nCropBottom); + aPoly.Scale(double(aScaleX), double(aScaleY)); + } + } + Fraction aMapPolyX(ww::nWrap100Percent, rOrigSize.Width()); Fraction aMapPolyY(ww::nWrap100Percent, rOrigSize.Height()); aPoly.Scale(double(aMapPolyX), double(aMapPolyY)); diff --git a/sw/source/filter/ww8/writerhelper.hxx b/sw/source/filter/ww8/writerhelper.hxx index 27dbd1b7b13c..aff22fb84aa4 100644 --- a/sw/source/filter/ww8/writerhelper.hxx +++ b/sw/source/filter/ww8/writerhelper.hxx @@ -613,7 +613,7 @@ namespace sw tools::Polygon PolygonFromPolyPolygon(const tools::PolyPolygon &rPolyPoly); /// Undo all scaling / move tricks of the wrap polygon done during import. - tools::Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon& rPolyPoly, const SwNoTextNode* pNd); + tools::Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon& rPolyPoly, const SwNoTextNode* pNd, bool bCorrectCrop); /** Make setting a drawing object's layer in a Writer document easy diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx index e1655946c80c..84fd91333033 100644 --- a/sw/source/filter/ww8/wrtw8esh.cxx +++ b/sw/source/filter/ww8/wrtw8esh.cxx @@ -2153,7 +2153,7 @@ sal_Int32 SwEscherEx::WriteFlyFrameAttr(const SwFrameFormat& rFormat, MSO_SPT eS const tools::PolyPolygon *pPolyPoly = pNd->HasContour(); if (pPolyPoly && pPolyPoly->Count()) { - tools::Polygon aPoly = CorrectWordWrapPolygonForExport(*pPolyPoly, pNd); + tools::Polygon aPoly = CorrectWordWrapPolygonForExport(*pPolyPoly, pNd, /*bCorrectCrop=*/false); SvMemoryStream aPolyDump; aPolyDump.SetEndian(SvStreamEndian::LITTLE); diff --git a/writerfilter/source/dmapper/WrapPolygonHandler.cxx b/writerfilter/source/dmapper/WrapPolygonHandler.cxx index e3bc6e4e2c94..3885427ee236 100644 --- a/writerfilter/source/dmapper/WrapPolygonHandler.cxx +++ b/writerfilter/source/dmapper/WrapPolygonHandler.cxx @@ -20,6 +20,7 @@ #include <com/sun/star/drawing/PointSequence.hpp> #include <com/sun/star/text/GraphicCrop.hpp> #include <comphelper/sequence.hxx> +#include <tools/mapunit.hxx> #include <ooxml/resourceids.hxx> @@ -97,7 +98,7 @@ WrapPolygon::Pointer_t WrapPolygon::correctWordWrapPolygon(const awt::Size & rSr const long nWrap100Percent = 21600; Fraction aMove(nWrap100Percent, rSrcSize.Width); - aMove = aMove * Fraction(15, 1); + aMove = aMove * Fraction(convertTwipToMm100(15), 1); awt::Point aMovePoint(aMove.operator long(), 0); pResult = move(aMovePoint); commit 83526f667416731de462418ee12c76dfbd6385cf Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed May 13 17:59:34 2020 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon May 18 16:59:49 2020 +0200 DOCX import: fix interaction between the crop and the wrap polygon of images Word first applies the crop, then applies the wrap polygon on the remaining visible part of the image. Writer applies the crop on the original bitmap, and even has explicit code to make sure the uncropped bitmap is used for the wrap polygon, see how SwFlyFrame::GetContour() calls SwNoTextFrame::GetGrfArea(), which will extend the resulting size based on cropping. Fix the problem by moving and scaling the wrap polygon, so it ends up where it would in Word. Also adapt testFdo76803, which had a similar crop+wrap polygon case, but the different there is quite small. (cherry picked from commit 2abe9837deee3823c7928a76b5b2f94f1464f1a3) Conflicts: writerfilter/CppunitTest_writerfilter_dmapper.mk writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx Change-Id: Iab2adaa81a33eb04e1806b17ed129ac50f5d2aa3 diff --git a/sw/qa/extras/ooxmlimport/data/wrap-poly-crop.docx b/sw/qa/extras/ooxmlimport/data/wrap-poly-crop.docx new file mode 100644 index 000000000000..1835a130d740 Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/wrap-poly-crop.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index e6f3a150b31f..513a5d64a7d4 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -898,17 +898,17 @@ DECLARE_OOXMLIMPORT_TEST(testFdo76803, "fdo76803.docx") CPPUNIT_ASSERT_EQUAL(sal_uInt32(4), aPolygon.count()); - CPPUNIT_ASSERT_EQUAL(double(-163), aPolygon.getB2DPoint(0).getX()); - CPPUNIT_ASSERT_EQUAL(double(0), aPolygon.getB2DPoint(0).getY()); + CPPUNIT_ASSERT_EQUAL(double(-162), aPolygon.getB2DPoint(0).getX()); + CPPUNIT_ASSERT_EQUAL(double(-35), aPolygon.getB2DPoint(0).getY()); - CPPUNIT_ASSERT_EQUAL(double(-163), aPolygon.getB2DPoint(1).getX()); - CPPUNIT_ASSERT_EQUAL(double(3661), aPolygon.getB2DPoint(1).getY()); + CPPUNIT_ASSERT_EQUAL(double(-162), aPolygon.getB2DPoint(1).getX()); + CPPUNIT_ASSERT_EQUAL(double(3510), aPolygon.getB2DPoint(1).getY()); - CPPUNIT_ASSERT_EQUAL(double(16987), aPolygon.getB2DPoint(2).getX()); - CPPUNIT_ASSERT_EQUAL(double(3661), aPolygon.getB2DPoint(2).getY()); + CPPUNIT_ASSERT_EQUAL(double(16892), aPolygon.getB2DPoint(2).getX()); + CPPUNIT_ASSERT_EQUAL(double(3510), aPolygon.getB2DPoint(2).getY()); - CPPUNIT_ASSERT_EQUAL(double(16987), aPolygon.getB2DPoint(3).getX()); - CPPUNIT_ASSERT_EQUAL(double(0), aPolygon.getB2DPoint(3).getY()); + CPPUNIT_ASSERT_EQUAL(double(16892), aPolygon.getB2DPoint(3).getX()); + CPPUNIT_ASSERT_EQUAL(double(-35), aPolygon.getB2DPoint(3).getY()); } DECLARE_OOXMLIMPORT_TEST(testUnbalancedColumnsCompat, "unbalanced-columns-compat.docx") @@ -1608,6 +1608,31 @@ DECLARE_OOXMLIMPORT_TEST(testTdf116486, "tdf116486.docx") CPPUNIT_ASSERT_EQUAL( OUString("4006"), aTop ); } +DECLARE_OOXMLIMPORT_TEST(testWrapPolyCrop, "wrap-poly-crop.docx") +{ + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage(); + uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); + drawing::PointSequenceSequence aContour; + xShape->getPropertyValue("ContourPolyPolygon") >>= aContour; + auto aPolyPolygon = basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(aContour); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aPolyPolygon.count()); + auto aPolygon = aPolyPolygon.getB2DPolygon(0); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(4), aPolygon.count()); + + // Ideally this would be 2352, because the graphic size in mm100, using the graphic's DPI is + // 10582, the lower 33% of the graphic is cropped, and the wrap polygon covers the middle third + // of the area vertically. Which means 10582*2/3 = 7054.67 is the cropped height, and the top of + // the middle third is 2351.55. + // + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 2361 + // - Actual : 3542 + // i.e. the wrap polygon covered a larger-than-correct area, which end the end means 3 lines + // were wrapping around the image, not only 2 as Word does it. + CPPUNIT_ASSERT_EQUAL(2361., aPolygon.getB2DPoint(0).getY()); +} + DECLARE_OOXMLIMPORT_TEST(testTdf117843, "tdf117843.docx") { uno::Reference<container::XNameAccess> xPageStyles = getStyles("PageStyles"); diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx index 76f36045ea4e..87745f93ae16 100644 --- a/writerfilter/source/dmapper/GraphicImport.cxx +++ b/writerfilter/source/dmapper/GraphicImport.cxx @@ -1324,6 +1324,17 @@ uno::Reference< text::XTextContent > GraphicImport::createGraphicObject( const b pCorrected = m_pImpl->mpWrapPolygon->correctWordWrapPolygonPixel(aGraphicSize); } } + + text::GraphicCrop aGraphicCrop; + xShapeProps->getPropertyValue("GraphicCrop") >>= aGraphicCrop; + if (aGraphicCrop.Top != 0 || aGraphicCrop.Bottom != 0 || aGraphicCrop.Left != 0 + || aGraphicCrop.Right != 0) + { + // Word's wrap polygon deals with a canvas which has the size of the already + // cropped graphic, correct our polygon to have the same render result. + pCorrected = pCorrected->correctCrop(aGraphicSize, aGraphicCrop); + } + if (pCorrected) { aContourPolyPolygon <<= pCorrected->getPointSequenceSequence(); diff --git a/writerfilter/source/dmapper/WrapPolygonHandler.cxx b/writerfilter/source/dmapper/WrapPolygonHandler.cxx index 010cf2e195a6..e3bc6e4e2c94 100644 --- a/writerfilter/source/dmapper/WrapPolygonHandler.cxx +++ b/writerfilter/source/dmapper/WrapPolygonHandler.cxx @@ -18,6 +18,7 @@ */ #include <com/sun/star/drawing/PointSequence.hpp> +#include <com/sun/star/text/GraphicCrop.hpp> #include <comphelper/sequence.hxx> #include <ooxml/resourceids.hxx> @@ -134,6 +135,23 @@ WrapPolygon::Pointer_t WrapPolygon::correctWordWrapPolygonPixel(const awt::Size return pResult; } +WrapPolygon::Pointer_t WrapPolygon::correctCrop(const awt::Size& rGraphicSize, + const text::GraphicCrop& rGraphicCrop) +{ + WrapPolygon::Pointer_t pResult; + + Fraction aScaleX(rGraphicSize.Width - rGraphicCrop.Left - rGraphicCrop.Right, + rGraphicSize.Width); + Fraction aScaleY(rGraphicSize.Height - rGraphicCrop.Top - rGraphicCrop.Bottom, + rGraphicSize.Height); + pResult = scale(aScaleX, aScaleY); + + awt::Point aMove(rGraphicCrop.Left, rGraphicCrop.Top); + pResult = pResult->move(aMove); + + return pResult; +} + drawing::PointSequenceSequence WrapPolygon::getPointSequenceSequence() const { drawing::PointSequenceSequence aPolyPolygon(1); diff --git a/writerfilter/source/dmapper/WrapPolygonHandler.hxx b/writerfilter/source/dmapper/WrapPolygonHandler.hxx index 3192408aa330..ae6502a13edf 100644 --- a/writerfilter/source/dmapper/WrapPolygonHandler.hxx +++ b/writerfilter/source/dmapper/WrapPolygonHandler.hxx @@ -26,6 +26,11 @@ #include <tools/fract.hxx> #include <vector> +namespace com::sun::star::text +{ +struct GraphicCrop; +} + namespace writerfilter { namespace dmapper { @@ -51,6 +56,8 @@ public: WrapPolygon::Pointer_t scale(const Fraction & rFractionX, const Fraction & rFractionY); WrapPolygon::Pointer_t correctWordWrapPolygon(const css::awt::Size & rSrcSize); WrapPolygon::Pointer_t correctWordWrapPolygonPixel(const css::awt::Size & rSrcSize); + WrapPolygon::Pointer_t correctCrop(const css::awt::Size& rGraphicSize, + const css::text::GraphicCrop& rGraphicCrop); css::drawing::PointSequenceSequence getPointSequenceSequence() const; }; commit 43c52057ae9d0a620611a3fcc484762dd06f47f5 Author: László Németh <nem...@numbertext.org> AuthorDate: Fri Feb 7 15:06:50 2020 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon May 18 16:59:30 2020 +0200 tdf#130494: DOCX import: limit paragraph-level character property expansion for the whole table paragraph based on the last character context. regression from 2ab481b038b62b1ff576ac4d49d03c1798cd7f84 (tdf#90069 DOCX: fix character style of new table rows) (cherry picked from commit abb9c7db8bcc06f907d39a7811711882161d5803) Conflicts: sw/qa/extras/ooxmlexport/ooxmlexport11.cxx writerfilter/source/dmapper/DomainMapper_Impl.cxx Change-Id: I49da23c268436488ff1537771869c38108113c12 diff --git a/sw/qa/extras/ooxmlexport/data/tdf130494.docx b/sw/qa/extras/ooxmlexport/data/tdf130494.docx new file mode 100644 index 000000000000..bc2050feaa55 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf130494.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx index 1833988a0b84..4e29e1bce375 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx @@ -515,6 +515,19 @@ DECLARE_OOXMLEXPORT_TEST(testTdf126723, "tdf126723.docx") CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraph(2), "ParaLeftMargin")); } +DECLARE_OOXMLEXPORT_TEST(testTdf130494, "tdf130494.docx") +{ + xmlDocPtr pXmlDoc = parseExport("word/document.xml"); + if (!pXmlDoc) + { + return; + } + + assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:pPr/w:rPr/w:highlight", "val", "yellow"); + // keep direct formatting of table cell paragraph with removed highlighting + assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r/w:rPr/w:highlight", 0); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 857822fd0625..5e75b7e43bca 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -1481,14 +1481,25 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap ) // fix table paragraph properties if ( xParaProps && m_nTableDepth > 0 ) { - uno::Sequence< beans::PropertyValue > aValues = pParaContext->GetPropertyValues(false); + uno::Sequence< beans::PropertyValue > aParaProps = pParaContext->GetPropertyValues(false); // tdf#90069 in tables, apply paragraph level character style also on // paragraph level to support its copy during insertion of new table rows - for( const auto& rProp : aValues ) + for( const auto& rParaProp : aParaProps ) { - if ( rProp.Name.startsWith("Char") && rProp.Name != "CharStyleName" && rProp.Name != "CharInteropGrabBag" ) - xParaProps->setPropertyValue( rProp.Name, rProp.Value ); + if ( m_pLastCharacterContext.get() && rParaProp.Name.startsWith("Char") && rParaProp.Name != "CharStyleName" && rParaProp.Name != "CharInteropGrabBag" ) + { + const uno::Sequence< beans::PropertyValue > aLastCharProps = m_pLastCharacterContext->GetPropertyValues( ); + + for( const auto& rLastCharProp : aLastCharProps ) + { + if ( rLastCharProp == rParaProp ) + { + xParaProps->setPropertyValue( rParaProp.Name, rParaProp.Value ); + break; + } + } + } } // tdf#128959 table paragraphs haven't got window and orphan controls commit 2b525eef03c7708bba9734ecbb543c8bf7e7aa3b Author: László Németh <nem...@numbertext.org> AuthorDate: Tue Jan 28 14:32:54 2020 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon May 18 16:50:51 2020 +0200 tdf#128959 DOCX import: fix missing text lines in tables Orphan/widow line break settings aren't always ignored by Writer table layout code, in this case, in vertically merged cells, resulting missing paragraph lines. As a workaround for interoperability, disable orphan/widow control in cell paragraphs during the DOCX import to get correct layout in Writer, too. (cherry picked from commit 8b13da71aedd094de0d351a4bd5ad43fdb4bddde) Conflicts: sw/qa/extras/layout/layout.cxx writerfilter/source/dmapper/DomainMapper_Impl.cxx Change-Id: I48fdb0a3bb421fd4df2c729e307a7ef483e3e772 diff --git a/sw/qa/extras/layout/data/tdf128959.docx b/sw/qa/extras/layout/data/tdf128959.docx new file mode 100644 index 000000000000..f22f66504478 Binary files /dev/null and b/sw/qa/extras/layout/data/tdf128959.docx differ diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 59f73e0b78bd..3b17cfdf2fd4 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -25,6 +25,7 @@ public: void testTdf117188(); void testTdf119875(); void testTdf123651(); + void testTdf128959(); CPPUNIT_TEST_SUITE(SwLayoutWriter); CPPUNIT_TEST(testTdf116830); @@ -35,6 +36,7 @@ public: CPPUNIT_TEST(testTdf117188); CPPUNIT_TEST(testTdf119875); CPPUNIT_TEST(testTdf123651); + CPPUNIT_TEST(testTdf128959); CPPUNIT_TEST_SUITE_END(); private: @@ -182,6 +184,27 @@ void SwLayoutWriter::testTdf123651() assertXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds", "top", "7639"); } +void SwLayoutWriter::testTdf128959() +{ + // no orphan/widow control in table cells + SwDoc* pDocument = createDoc("tdf128959.docx"); + CPPUNIT_ASSERT(pDocument); + discardDumpedLayout(); + xmlDocPtr pXmlDoc = parseLayoutDump(); + + // first two lines of the paragraph in the split table cell on the first page + // (these lines were completely lost) + assertXPath( + pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[1]/txt[1]/LineBreak[1]", "Line", + "a)Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue "); + assertXPath( + pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[1]/txt[1]/LineBreak[2]", "Line", + "massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit "); + // last line of the paragraph in the split table cell on the second page + assertXPath(pXmlDoc, "/root/page[2]/body/tab[1]/row[1]/cell[1]/txt[1]/LineBreak[1]", "Line", + "amet commodo magna eros quis urna."); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwLayoutWriter); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index a6f62a7b4f23..857822fd0625 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -1478,17 +1478,23 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap ) } } - // tdf#90069 in tables, apply paragraph level character style also on - // paragraph level to support its copy during insertion of new table rows + // fix table paragraph properties if ( xParaProps && m_nTableDepth > 0 ) { uno::Sequence< beans::PropertyValue > aValues = pParaContext->GetPropertyValues(false); + // tdf#90069 in tables, apply paragraph level character style also on + // paragraph level to support its copy during insertion of new table rows for( const auto& rProp : aValues ) { if ( rProp.Name.startsWith("Char") && rProp.Name != "CharStyleName" && rProp.Name != "CharInteropGrabBag" ) xParaProps->setPropertyValue( rProp.Name, rProp.Value ); } + + // tdf#128959 table paragraphs haven't got window and orphan controls + uno::Any aAny = uno::makeAny(static_cast<sal_Int8>(0)); + xParaProps->setPropertyValue("ParaOrphans", aAny); + xParaProps->setPropertyValue("ParaWidows", aAny); } } if( !bKeepLastParagraphProperties ) commit cc606aa0a0441ace76c553eb5b61a30fab5f9776 Author: Miklos Vajna <vmik...@collabora.co.uk> AuthorDate: Wed Jul 11 14:29:36 2018 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon May 18 16:03:29 2020 +0200 tdf#118672 sw layout, TabOverMargin: allow using the area over the tab portion TabOverMargin in general is about allowing the cursor to jump over a margin if there is an explicit tab stop there. A corner-case is what to do when there is enough content so a line break is necessary for the characters after the tab portion. Allow using the area up to the edge of the whole text frame (i.e. over the tab position), this matches what Word does. (cherry picked from commit 4b345f95ce7cb09011892bf465cfdf3811adaf8e) Conflicts: sw/qa/extras/layout/layout.cxx sw/source/core/text/inftxt.cxx sw/source/core/text/xmldump.cxx [ Just the sw layout xml dump part. ] Change-Id: Ie86edf030d54fba556eee26e7ea563fb8d4fbee4 diff --git a/sw/source/core/text/xmldump.cxx b/sw/source/core/text/xmldump.cxx index 379a8bc46e3e..f6f88b038798 100644 --- a/sw/source/core/text/xmldump.cxx +++ b/sw/source/core/text/xmldump.cxx @@ -32,6 +32,8 @@ class XmlPortionDumper:public SwPortionHandler private: xmlTextWriterPtr writer; sal_Int32 ofs; + const OUString& m_rText; + OUString m_aLine; static const char* getTypeName( sal_uInt16 nType ) { @@ -105,7 +107,7 @@ class XmlPortionDumper:public SwPortionHandler public: - explicit XmlPortionDumper( xmlTextWriterPtr some_writer ):writer( some_writer ), ofs( 0 ) + explicit XmlPortionDumper( xmlTextWriterPtr some_writer, const OUString& rText ):writer( some_writer ), ofs( 0 ), m_rText(rText) { } @@ -120,7 +122,6 @@ class XmlPortionDumper:public SwPortionHandler sal_Int32 nHeight, sal_Int32 nWidth) override { - ofs += nLength; xmlTextWriterStartElement( writer, BAD_CAST( "Text" ) ); xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "nLength" ), @@ -132,8 +133,13 @@ class XmlPortionDumper:public SwPortionHandler xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", (int)nHeight); if (nWidth > 0) xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", (int)nWidth); + if (nLength > 0) + xmlTextWriterWriteAttribute(writer, BAD_CAST("Portion"), + BAD_CAST(m_rText.copy(ofs, nLength).toUtf8().getStr())); xmlTextWriterEndElement( writer ); + m_aLine += m_rText.copy(ofs, nLength); + ofs += nLength; } /** @@ -174,6 +180,7 @@ class XmlPortionDumper:public SwPortionHandler pFont->dumpAsXml(writer); xmlTextWriterEndElement( writer ); + m_aLine += rText; ofs += nLength; } @@ -184,6 +191,12 @@ class XmlPortionDumper:public SwPortionHandler xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "nWidth" ), "%i", ( int ) nWidth ); + if (!m_aLine.isEmpty()) + { + xmlTextWriterWriteAttribute(writer, BAD_CAST("Line"), + BAD_CAST(m_aLine.toUtf8().getStr())); + m_aLine.clear(); + } xmlTextWriterEndElement( writer ); } @@ -348,7 +361,7 @@ void SwFrame::dumpAsXml( xmlTextWriterPtr writer ) const RTL_TEXTENCODING_UTF8 ); xmlTextWriterWriteString( writer, reinterpret_cast<const xmlChar *>(aText8.getStr( )) ); - XmlPortionDumper pdumper( writer ); + XmlPortionDumper pdumper( writer, aText ); pTextFrame->VisitPortions( pdumper ); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits