svx/qa/unit/data/0-width-text-wrap.pptx              |binary
 svx/qa/unit/sdr.cxx                                  |   51 ++++++++++++++-----
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx |   28 +++++++++-
 3 files changed, 66 insertions(+), 13 deletions(-)

New commits:
commit 0d55c821b72a4eba6f1696504888419ebcb23a20
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Jan 6 10:23:44 2021 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Jan 7 10:51:37 2021 +0100

    tdf#134288 svx: fix rendering of text on a zero-width shape
    
    We have conflicting requirements here: on one hand, the shape is zero
    width, so the text area is also zero.  On the other hand, we put some
    text on the shape, which should be visible.
    
    The result was that the left/right text margin (2x250 mm100) was counted
    as part of the text area, so we put a few (but not 1) characters / line
    for zero width. Fix this to be PowerPoint-compatible: as the width
    decreases, we break the text up to more and more lines, but if the width
    is 0, then we don't break it up at all.
    
    An alternative would be to do this later in
    SdrTextObj::impDecomposeBlockTextPrimitive(), but there we no longer
    know the width is really 0, because the text margins and some small
    increase (+1 to be an inclusive range, +1 to have a non-zero scale) is
    already added to the original width.
    
    (cherry picked from commit 65e2ef43f186164729e1cc071b805bc1a7125cfe)
    
    Conflicts:
            svx/qa/unit/sdr.cxx
    
    Change-Id: Ieaa3e726bc5d37983b6221452e14f01db315f790
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108872
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/svx/qa/unit/data/0-width-text-wrap.pptx 
b/svx/qa/unit/data/0-width-text-wrap.pptx
new file mode 100644
index 000000000000..17349924d89b
Binary files /dev/null and b/svx/qa/unit/data/0-width-text-wrap.pptx differ
diff --git a/svx/qa/unit/sdr.cxx b/svx/qa/unit/sdr.cxx
index b087e1144ba8..cde622cffe6f 100644
--- a/svx/qa/unit/sdr.cxx
+++ b/svx/qa/unit/sdr.cxx
@@ -51,19 +51,14 @@ public:
         test::BootstrapFixture::tearDown();
     }
     uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+
+    drawinglayer::primitive2d::Primitive2DContainer
+    renderPageToPrimitives(const uno::Reference<drawing::XDrawPage>& 
xDrawPage);
 };
 
-CPPUNIT_TEST_FIXTURE(SdrTest, testShadowScaleOrigin)
+drawinglayer::primitive2d::Primitive2DContainer
+SdrTest::renderPageToPrimitives(const uno::Reference<drawing::XDrawPage>& 
xDrawPage)
 {
-    // Load a document containing a custom shape.
-    test::Directories aDirectories;
-    OUString aURL = 
aDirectories.getURLFromSrc("svx/qa/unit/data/shadow-scale-origin.pptx");
-    getComponent() = loadFromDesktop(aURL);
-    uno::Reference<drawing::XDrawPagesSupplier> 
xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
-    uno::Reference<drawing::XDrawPage> 
xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
-                                                 uno::UNO_QUERY);
-
-    // Render it.
     auto pDrawPage = dynamic_cast<SvxDrawPage*>(xDrawPage.get());
     CPPUNIT_ASSERT(pDrawPage);
     SdrPage* pSdrPage = pDrawPage->GetSdrPage();
@@ -73,8 +68,20 @@ CPPUNIT_TEST_FIXTURE(SdrTest, testShadowScaleOrigin)
     const sdr::contact::ViewObjectContact& rDrawPageVOContact
         = pSdrPage->GetViewContact().GetViewObjectContact(aObjectContact);
     sdr::contact::DisplayInfo aDisplayInfo;
+    return rDrawPageVOContact.getPrimitive2DSequenceHierarchy(aDisplayInfo);
+}
+
+CPPUNIT_TEST_FIXTURE(SdrTest, testShadowScaleOrigin)
+{
+    // Load a document containing a custom shape.
+    test::Directories aDirectories;
+    OUString aURL = 
aDirectories.getURLFromSrc("svx/qa/unit/data/shadow-scale-origin.pptx");
+    getComponent() = loadFromDesktop(aURL);
+    uno::Reference<drawing::XDrawPagesSupplier> 
xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> 
xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+                                                 uno::UNO_QUERY);
     drawinglayer::primitive2d::Primitive2DContainer xPrimitiveSequence
-        = rDrawPageVOContact.getPrimitive2DSequenceHierarchy(aDisplayInfo);
+        = renderPageToPrimitives(xDrawPage);
 
     // Examine the created primitives.
     drawinglayer::Primitive2dXmlDump aDumper;
@@ -89,6 +96,28 @@ CPPUNIT_TEST_FIXTURE(SdrTest, testShadowScaleOrigin)
     CPPUNIT_ASSERT_EQUAL(-705., std::round(fShadowX));
     CPPUNIT_ASSERT_EQUAL(-685., std::round(fShadowY));
 }
+
+CPPUNIT_TEST_FIXTURE(SdrTest, testZeroWidthTextWrap)
+{
+    // Load a document containing a 0-width shape with text.
+    test::Directories aDirectories;
+    OUString aURL = 
aDirectories.getURLFromSrc("svx/qa/unit/data/0-width-text-wrap.pptx");
+    getComponent() = loadFromDesktop(aURL);
+    uno::Reference<drawing::XDrawPagesSupplier> 
xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> 
xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+                                                 uno::UNO_QUERY);
+    drawinglayer::primitive2d::Primitive2DContainer xPrimitiveSequence
+        = renderPageToPrimitives(xDrawPage);
+
+    // Examine the created primitives.
+    drawinglayer::Primitive2dXmlDump aDumper;
+    xmlDocUniquePtr pDocument = aDumper.dumpAndParse(xPrimitiveSequence);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 12
+    // i.e. the text on the only shape on the slide had 12 lines, not a single 
one.
+    assertXPath(pDocument, "//textsimpleportion", 1);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx 
b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
index 4cecdadb300d..504862a64229 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -278,12 +278,36 @@ namespace drawinglayer::primitive2d
 
                 // create a range describing the wanted text position and size 
(aTextAnchorRange). This
                 // means to use the text distance values here
-                const basegfx::B2DPoint aTopLeft(aSnapRange.getMinX() + 
rText.getTextLeftDistance(), aSnapRange.getMinY() + 
rText.getTextUpperDistance());
-                const basegfx::B2DPoint aBottomRight(aSnapRange.getMaxX() - 
rText.getTextRightDistance(), aSnapRange.getMaxY() - 
rText.getTextLowerDistance());
+                sal_Int32 nTextLeftDistance = rText.getTextLeftDistance();
+                // If the margin is larger than the entire width of the text 
area, then limit the
+                // margin.
+                if (nTextLeftDistance > aSnapRange.getWidth())
+                    nTextLeftDistance = aSnapRange.getWidth();
+                sal_Int32 nTextRightDistance = rText.getTextRightDistance();
+                if (nTextRightDistance > aSnapRange.getWidth())
+                    nTextRightDistance = aSnapRange.getWidth();
+                const basegfx::B2DPoint aTopLeft(aSnapRange.getMinX() + 
nTextLeftDistance,
+                                                 aSnapRange.getMinY()
+                                                     + 
rText.getTextUpperDistance());
+                const basegfx::B2DPoint aBottomRight(aSnapRange.getMaxX() - 
nTextRightDistance,
+                                                     aSnapRange.getMaxY()
+                                                         - 
rText.getTextLowerDistance());
                 basegfx::B2DRange aTextAnchorRange;
                 aTextAnchorRange.expand(aTopLeft);
                 aTextAnchorRange.expand(aBottomRight);
 
+                if (aTextAnchorRange.getWidth() == 0)
+                {
+                    // If the shape has no width, then don't attempt to break 
the text into multiple
+                    // lines, not a single character would satisfy a zero 
width requirement.
+                    // SdrTextObj::impDecomposeBlockTextPrimitive() uses the 
same constant to
+                    // effectively set no limits.
+                    aTextAnchorRange.expand(
+                        basegfx::B2DPoint(aTopLeft.getX() - 1000000, 
aTopLeft.getY()));
+                    aTextAnchorRange.expand(
+                        basegfx::B2DPoint(aBottomRight.getX() + 1000000, 
aBottomRight.getY()));
+                }
+
                 // now create a transformation from this basic range 
(aTextAnchorRange)
                 // #i121494# if we have no scale use at least 1.0 to have a 
carrier e.g. for
                 // mirror values, else these will get lost
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to