diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2023-01-23 11:38:52 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2023-01-23 16:56:43 +0000 |
commit | 23555ec4058521262860d48d976eba8563d9ba98 (patch) | |
tree | f23eaf70086c834e56ba20dc7930999954831d2a | |
parent | 6543eb9a5cda3cbd2cd46f35c7f0bc940cd69a45 (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.docx | bin | 0 -> 16667 bytes | |||
-rw-r--r-- | sw/qa/extras/layout/layout2.cxx | 171 | ||||
-rw-r--r-- | sw/source/core/text/porlay.cxx | 19 |
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 Binary files differnew file mode 100644 index 000000000000..357f64f9a940 --- /dev/null +++ b/sw/qa/extras/layout/data/tdf153136.docx 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() |