sw/CppunitTest_sw_core_text.mk   |    1 
 sw/qa/core/text/data/ruby.fodt   |   25 +++++++++++++++++++++
 sw/qa/core/text/text.cxx         |   46 +++++++++++++++++++++++++++++++++++++++
 sw/source/core/text/porlay.hxx   |    2 -
 sw/source/core/text/pormulti.cxx |    2 -
 5 files changed, 74 insertions(+), 2 deletions(-)

New commits:
commit 168065841250c190808261cf65afa00f9ecd52e7
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Sep 13 19:27:48 2021 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Tue Sep 14 11:41:03 2021 +0200

    tdf#144305 sw: fix rendering of ruby portions with non-default ruby 
alignment
    
    Regression from 301278b656e76b6f42af5cf8a6f5c6c02acfffeb (sw: allow the
    height of a line to be larger than 65536 twips, 2021-05-20), the problem
    was that changing from sal_uInt16 to sal_uInt32 broke
    SwRubyPortion::Adjust_(), which relied on integer promotion rules to
    have a negative diff.
    
    Old storage size was smaller than int, so got promoted to signed int, so
    the result could be a small negative number.
    
    New storage size is an unsigned int, so no promotion happens, so the new
    result was a large positive number.
    
    Fix this by casting to signed int explicitly.
    
    Change-Id: I8778c1bd0d62e27c99d4ceb1bb7bc6107a179803
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122048
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit 0c3e47cc2f0570a7cd8ff4889763991a86b29f26)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122066
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk
index cb4801accac9..6f19ff690f5a 100644
--- a/sw/CppunitTest_sw_core_text.mk
+++ b/sw/CppunitTest_sw_core_text.mk
@@ -40,6 +40,7 @@ $(eval $(call gb_CppunitTest_use_externals,sw_core_text,\
 $(eval $(call gb_CppunitTest_set_include,sw_core_text,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
+    -I$(SRCDIR)/sw/source/core/text \
     -I$(SRCDIR)/sw/source/uibase/inc \
     -I$(SRCDIR)/sw/qa/inc \
     $$(INCLUDE) \
diff --git a/sw/qa/core/text/data/ruby.fodt b/sw/qa/core/text/data/ruby.fodt
new file mode 100644
index 000000000000..b5a0e23d2c53
--- /dev/null
+++ b/sw/qa/core/text/data/ruby.fodt
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+  <office:font-face-decls>
+  </office:font-face-decls>
+  <office:styles>
+  </office:styles>
+  <office:automatic-styles>
+    <style:style style:name="Ru1" style:family="ruby">
+      <style:ruby-properties style:ruby-align="left" 
style:ruby-position="above" loext:ruby-position="above"/>
+    </style:style>
+    <style:style style:name="Ru2" style:family="ruby">
+      <style:ruby-properties style:ruby-align="center" 
style:ruby-position="above" loext:ruby-position="above"/>
+    </style:style>
+    <style:style style:name="Ru3" style:family="ruby">
+      <style:ruby-properties style:ruby-align="right" 
style:ruby-position="above" loext:ruby-position="above"/>
+    </style:style>
+  </office:automatic-styles>
+  <office:master-styles>
+  </office:master-styles>
+  <office:body>
+    <office:text>
+      <text:p text:style-name="P1">Ruby test: <text:ruby 
text:style-name="Ru1"><text:ruby-base>base text</text:ruby-base><text:ruby-text 
text:style-name="Rubies">ruby (left)</text:ruby-text></text:ruby> <text:ruby 
text:style-name="Ru2"><text:ruby-base>base 
text</text:ruby-base><text:ruby-text>ruby (center)</text:ruby-text></text:ruby> 
<text:ruby text:style-name="Ru3"><text:ruby-base>base 
text</text:ruby-base><text:ruby-text>ruby 
(right)</text:ruby-text></text:ruby></text:p>
+    </office:text>
+  </office:body>
+</office:document>
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index be6406f6b654..6832ad2cb436 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -21,6 +21,12 @@
 #include <docsh.hxx>
 #include <unotxdoc.hxx>
 #include <wrtsh.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <rootfrm.hxx>
+#include <txtfrm.hxx>
+
+#include <porlay.hxx>
+#include <pormulti.hxx>
 
 constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/core/text/data/";
 
@@ -170,6 +176,46 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testLineWidth)
     CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(65536), nNewLeft - nOldLeft);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testRuby)
+{
+    // Given a document with multiple ruby portions:
+    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "ruby.fodt");
+
+    // When laying out that document:
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+
+    // Then make sure that no unwanted margin portions are created, making the 
actual text
+    // invisible:
+    SwFrame* pPageFrame = pLayout->GetLower();
+    SwFrame* pBodyFrame = pPageFrame->GetLower();
+    SwFrame* pFrame = pBodyFrame->GetLower();
+    CPPUNIT_ASSERT(pFrame->IsTextFrame());
+    auto pTextFrame = static_cast<SwTextFrame*>(pFrame);
+    SwParaPortion* pPara = pTextFrame->GetPara();
+    bool bFirst = true;
+    for (SwLinePortion* pPor = pPara->GetFirstPortion(); pPor; pPor = 
pPor->GetNextPortion())
+    {
+        // Look for multi-portions in the only paragraph of the document.
+        if (pPor->GetWhichPor() != PortionType::Multi)
+        {
+            continue;
+        }
+
+        if (bFirst)
+        {
+            bFirst = false;
+            continue;
+        }
+
+        // The second multi-portion has two lines, check the start of the 
second line.
+        auto pMulti = static_cast<SwMultiPortion*>(pPor);
+        // Without the accompanying fix in place, this test would have failed, 
as the portion was a
+        // margin portion, not a text portion. The margin was so large that 
the actual text portion was
+        // hidden. No margin is needed here at all.
+        
CPPUNIT_ASSERT(pMulti->GetRoot().GetNext()->GetFirstPortion()->IsTextPortion());
+    }
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/porlay.hxx b/sw/source/core/text/porlay.hxx
index 5234a537fa4c..bff0bd559309 100644
--- a/sw/source/core/text/porlay.hxx
+++ b/sw/source/core/text/porlay.hxx
@@ -75,7 +75,7 @@ public:
 
 /// Collection of SwLinePortion instances, representing one line of text.
 /// Typically owned by an SwParaPortion.
-class SwLineLayout : public SwTextPortion
+class SW_DLLPUBLIC SwLineLayout : public SwTextPortion
 {
 private:
     SwLineLayout *m_pNext;                // The next Line
diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx
index b94302bd8ed7..98b8df7b643f 100644
--- a/sw/source/core/text/pormulti.cxx
+++ b/sw/source/core/text/pormulti.cxx
@@ -630,7 +630,7 @@ SwRubyPortion::SwRubyPortion( const SwMultiCreator& 
rCreate, const SwFont& rFnt,
 // If there is a tabulator in smaller line, no adjustment is possible.
 void SwRubyPortion::Adjust_( SwTextFormatInfo &rInf )
 {
-    SwTwips nLineDiff = GetRoot().Width() - GetRoot().GetNext()->Width();
+    SwTwips nLineDiff = o3tl::narrowing<SwTwips>(GetRoot().Width()) - 
GetRoot().GetNext()->Width();
     TextFrameIndex const nOldIdx = rInf.GetIdx();
     if( !nLineDiff )
         return;

Reply via email to