summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2023-01-23 11:38:52 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2023-01-23 16:56:43 +0000
commit23555ec4058521262860d48d976eba8563d9ba98 (patch)
treef23eaf70086c834e56ba20dc7930999954831d2a
parent6543eb9a5cda3cbd2cd46f35c7f0bc940cd69a45 (diff)
tdf#153136: fix IgnoreTabsAndBlanksForLineCalculation compat flag
It should handle SPACE, EN SPACE, EM SPACE, FOUR-PER-EM SPACE ,and IDEOGRAPHIC SPACE, but not SIX-PER-EM SPACE. The latter was mistakenly added in commit 9ee96273a2090b63e0f579a1e9c9cef780756e6d "tdf#123703 strip six-em-space (U+2006) at line break" (2019-08-24). Change-Id: I857f303eb19e19f067ad47933fa4b7eb96ce5ca0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145995 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r--sw/qa/extras/layout/data/tdf153136.docxbin0 -> 16667 bytes
-rw-r--r--sw/qa/extras/layout/layout2.cxx171
-rw-r--r--sw/source/core/text/porlay.cxx19
3 files changed, 183 insertions, 7 deletions
diff --git a/sw/qa/extras/layout/data/tdf153136.docx b/sw/qa/extras/layout/data/tdf153136.docx
new file mode 100644
index 000000000000..357f64f9a940
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf153136.docx
Binary files differ
diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx
index 0fa9f9978857..6ff56e5ac49c 100644
--- a/sw/qa/extras/layout/layout2.cxx
+++ b/sw/qa/extras/layout/layout2.cxx
@@ -2573,6 +2573,177 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152031)
nLeft_Row2);
}
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf153136)
+{
+ createSwDoc("tdf153136.docx");
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ const sal_Int32 small = 300; // Small-height lines are around 276 twip
+ const sal_Int32 large = 1000; // Large-height lines are 1104 twip or more
+
+ // Page 1: standalone paragraphs
+
+ // U+0009 CHARACTER TABULATION: height is ignored
+ sal_Int32 height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[1]", "height").toInt32();
+ CPPUNIT_ASSERT_LESS(small, height);
+
+ // U+0020 SPACE: height is ignored
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[2]", "height").toInt32();
+ CPPUNIT_ASSERT_LESS(small, height);
+
+ // U+00A0 NO-BREAK SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[3]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+1680 OGHAM SPACE MARK: height is considered; not tested, because Liberation Serif lacks it
+
+ // U+2000 EN QUAD: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[4]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2001 EM QUAD: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[5]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2002 EN SPACE: height is ignored
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[6]", "height").toInt32();
+ CPPUNIT_ASSERT_LESS(small, height);
+
+ // U+2003 EM SPACE: height is ignored
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[7]", "height").toInt32();
+ CPPUNIT_ASSERT_LESS(small, height);
+
+ // U+2004 THREE-PER-EM SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[8]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2005 FOUR-PER-EM SPACE: height is ignored
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[9]", "height").toInt32();
+ CPPUNIT_ASSERT_LESS(small, height);
+
+ // U+2006 SIX-PER-EM SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[10]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2007 FIGURE SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[11]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2008 PUNCTUATION SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[12]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2009 THIN SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[13]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+200A HAIR SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[14]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+202F NARROW NO-BREAK SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[1]//SwLineLayout)[15]", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+205F MEDIUM MATHEMATICAL SPACE: height is considered; not tested, because Liberation Serif lacks it
+ // U+3000 IDEOGRAPHIC SPACE: height is ignored; not tested, because Liberation Serif lacks it
+
+ // Page 2: table rows (no paragraph-level size DF)
+
+ // U+0020 SPACE: height is ignored
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[1]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_LESS(small, height);
+
+ // U+00A0 NO-BREAK SPACE: height is considered (1104 or so)
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[2]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+1680 OGHAM SPACE MARK: height is considered; not tested, because Liberation Serif lacks it
+
+ // U+2000 EN QUAD: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[3]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2001 EM QUAD: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[4]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2002 EN SPACE: height is ignored
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[5]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_LESS(small, height);
+
+ // U+2003 EM SPACE: height is ignored
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[6]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_LESS(small, height);
+
+ // U+2004 THREE-PER-EM SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[7]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2005 FOUR-PER-EM SPACE: height is ignored
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[8]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_LESS(small, height);
+
+ // U+2006 SIX-PER-EM SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[9]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2007 FIGURE SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[10]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2008 PUNCTUATION SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[11]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+2009 THIN SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[12]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+200A HAIR SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[13]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+202F NARROW NO-BREAK SPACE: height is considered
+ height = getXPath(pXmlDoc, "(/root/page[2]//row)[14]/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_GREATER(large, height);
+
+ // U+205F MEDIUM MATHEMATICAL SPACE: height is considered; not tested, because Liberation Serif lacks it
+ // U+3000 IDEOGRAPHIC SPACE: height is ignored; not tested, because Liberation Serif lacks it
+
+ // TODO: page 3, with table having paragraphs with paragraph-level size DF;
+ // all rows should have large height
+
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[1]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[2]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[3]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[4]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[5]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[6]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[7]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[8]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[9]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[10]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[11]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[12]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[13]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+ // height = getXPath(pXmlDoc, "(/root/page[3]//row)[14]/infos/bounds", "height").toInt32();
+ // CPPUNIT_ASSERT_GREATER(large, height);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 65f2b4de3bae..5e50f7ad5873 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -355,20 +355,25 @@ void SwLineLayout::CreateSpaceAdd( const tools::Long nInit )
SetLLSpaceAdd( nInit, 0 );
}
-// Returns true if there are only blanks in [nStt, nEnd[
+// #i3952# Returns true if there are only blanks in [nStt, nEnd[
+// Used to implement IgnoreTabsAndBlanksForLineCalculation compat flag
static bool lcl_HasOnlyBlanks(std::u16string_view rText, TextFrameIndex nStt, TextFrameIndex nEnd)
{
- bool bBlankOnly = true;
while ( nStt < nEnd )
{
- const sal_Unicode cChar = rText[ sal_Int32(nStt++) ];
- if ( ' ' != cChar && CH_FULL_BLANK != cChar && CH_SIX_PER_EM != cChar )
+ switch (rText[sal_Int32(nStt++)])
{
- bBlankOnly = false;
- break;
+ case 0x0020: // SPACE
+ case 0x2002: // EN SPACE
+ case 0x2003: // EM SPACE
+ case 0x2005: // FOUR-PER-EM SPACE
+ case 0x3000: // IDEOGRAPHIC SPACE
+ continue;
+ default:
+ return false;
}
}
- return bBlankOnly;
+ return true;
}
// Swapped out from FormatLine()