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

Reply via email to