diff options
author | Jonathan Clark <jonathan@libreoffice.org> | 2025-02-27 00:55:11 -0700 |
---|---|---|
committer | Jonathan Clark <jonathan@libreoffice.org> | 2025-02-27 15:38:18 +0100 |
commit | fac5695974d8a2197edba1e9f69f86621196cae1 (patch) | |
tree | da3ba7521adbe90fa04941edc32f46e626a91079 /sw/qa | |
parent | 406afe11711df9fcabbc829fcff00aef2f44c1d9 (diff) |
tdf#164140 sw: Fix invalid string indices in kashida justification
During layout, Writer has to mark certain lines and positions as
ineligible for kashida. These lines and positions are stored using
string indices on a per-paragraph basis.
This change fixes a bug causing corruption of these kashida
ineligibility indices during editing. Writer tries to reuse the existing
layouts of lines whenever possible. Since these kashida indices are
computed at the same time as layout, and the paragraph-relative subrange
of a line may be different after inserting or deleting text in previous
lines, the stored indices would point to different parts of the
paragraph string than intended.
Change-Id: Idb67d0a217841dc0743ed716ef8214d10e7b560b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182286
Tested-by: Jenkins
Reviewed-by: Jonathan Clark <jonathan@libreoffice.org>
Diffstat (limited to 'sw/qa')
-rw-r--r-- | sw/qa/core/uwriter.cxx | 4 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/data/tdf164140.fodt | 117 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter9.cxx | 51 |
3 files changed, 170 insertions, 2 deletions
diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx index 8a03254e7c5d..36573a79153f 100644 --- a/sw/qa/core/uwriter.cxx +++ b/sw/qa/core/uwriter.cxx @@ -1986,9 +1986,9 @@ void SwDocTest::testTdf156211() CPPUNIT_ASSERT(!oSI.IsKashidaLine(TextFrameIndex{ 95 })); - oSI.ClearNoKashidaLine(TextFrameIndex{ 0 }, TextFrameIndex{ 89 }); + oSI.ClearNoKashidaLines(); - CPPUNIT_ASSERT(!oSI.IsKashidaLine(TextFrameIndex{ 95 })); + CPPUNIT_ASSERT(oSI.IsKashidaLine(TextFrameIndex{ 95 })); } void SwDocTest::testFillRubyList() diff --git a/sw/qa/extras/uiwriter/data/tdf164140.fodt b/sw/qa/extras/uiwriter/data/tdf164140.fodt new file mode 100644 index 000000000000..ec37896c25b7 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/tdf164140.fodt @@ -0,0 +1,117 @@ +<?xml version='1.0' encoding='UTF-8'?> +<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:meta><meta:creation-date>2025-02-27T01:08:55.794571331</meta:creation-date><meta:editing-duration>PT1M23S</meta:editing-duration><meta:editing-cycles>3</meta:editing-cycles><meta:generator>LibreOfficeDev/25.8.0.0.alpha0$Linux_X86_64 LibreOffice_project/d09f3f24c38eda633825f4ac214731db06bc9a9a</meta:generator><dc:date>2025-02-27T01:18:29.823738756</dc:date><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="1" meta:word-count="52" meta:character-count="312" meta:non-whitespace-character-count="260"/></office:meta> + <office:font-face-decls> + <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/> + <style:font-face style:name="Lohit Devanagari1" svg:font-family="'Lohit Devanagari'" style:font-family-generic="system" style:font-pitch="variable"/> + <style:font-face style:name="Noto Sans" svg:font-family="'Noto Sans'" style:font-adornments="Regular" style:font-family-generic="swiss" style:font-pitch="variable"/> + <style:font-face style:name="Noto Sans Arabic" svg:font-family="'Noto Sans Arabic'" style:font-adornments="Regular" style:font-family-generic="swiss" style:font-pitch="variable"/> + <style:font-face style:name="Noto Serif CJK SC" svg:font-family="'Noto Serif CJK SC'" style:font-family-generic="system" style:font-pitch="variable"/> + </office:font-face-decls> + <office:styles> + <style:default-style style:family="graphic"> + <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.1181in" draw:shadow-offset-y="0.1181in" draw:start-line-spacing-horizontal="0.1114in" draw:start-line-spacing-vertical="0.1114in" draw:end-line-spacing-horizontal="0.1114in" draw:end-line-spacing-vertical="0.1114in" style:writing-mode="lr-tb" style:flow-with-text="false"/> + <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" loext:tab-stop-distance="0in" style:writing-mode="lr-tb" style:font-independent-line-spacing="false"> + <style:tab-stops/> + </style:paragraph-properties> + <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/> + </style:default-style> + <style:default-style style:family="paragraph"> + <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" fo:hyphenation-keep="auto" loext:hyphenation-keep-type="column" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="0.4925in" style:writing-mode="page"/> + <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/> + </style:default-style> + <style:default-style style:family="table"> + <style:table-properties table:border-model="collapsing"/> + </style:default-style> + <style:default-style style:family="table-row"> + <style:table-row-properties fo:keep-together="auto"/> + </style:default-style> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <text:outline-style style:name="Outline"> + <text:outline-level-style text:level="1" loext:num-list-format="%1%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="2" loext:num-list-format="%2%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="3" loext:num-list-format="%3%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="4" loext:num-list-format="%4%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="5" loext:num-list-format="%5%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="6" loext:num-list-format="%6%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="7" loext:num-list-format="%7%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="8" loext:num-list-format="%8%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="9" loext:num-list-format="%9%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="10" loext:num-list-format="%10%" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + </text:outline-style> + <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/> + <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/> + <text:linenumbering-configuration text:number-lines="false" text:offset="0.1965in" style:num-format="1" text:number-position="left" text:increment="5"/> + </office:styles> + <office:automatic-styles> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:paragraph-properties fo:text-align="justify" style:justify-single-word="false" style:writing-mode="rl-tb"/> + <style:text-properties style:font-name="Noto Sans" style:font-name-complex="Noto Sans Arabic" style:language-complex="ar" style:country-complex="SA"/> + </style:style> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="8.5in" fo:page-height="11in" style:num-format="1" style:print-orientation="portrait" fo:margin-top="0.7874in" fo:margin-bottom="0.7874in" fo:margin-left="0.7874in" fo:margin-right="0.7874in" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.278in" style:layout-grid-ruby-height="0.139in" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0in" loext:margin-gutter="0in"> + <style:footnote-sep style:width="0.0071in" style:distance-before-sep="0.0398in" style:distance-after-sep="0.0398in" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:page-layout-properties> + <style:header-style/> + <style:footer-style/> + </style:page-layout> + <style:style style:name="dp1" style:family="drawing-page"> + <style:drawing-page-properties draw:background-size="full"/> + </style:style> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-layout-name="pm1" draw:style-name="dp1"/> + </office:master-styles> + <office:body> + <office:text> + <text:sequence-decls> + <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/> + <text:sequence-decl text:display-outline-level="0" text:name="Table"/> + <text:sequence-decl text:display-outline-level="0" text:name="Text"/> + <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/> + <text:sequence-decl text:display-outline-level="0" text:name="Figure"/> + </text:sequence-decls> + <text:p text:style-name="P1">متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن <text:s/>آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی متن آزمایشی</text:p> + </office:text> + </office:body> +</office:document>
\ No newline at end of file diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx b/sw/qa/extras/uiwriter/uiwriter9.cxx index daf0402ba1cf..93d356c6cf0e 100644 --- a/sw/qa/extras/uiwriter/uiwriter9.cxx +++ b/sw/qa/extras/uiwriter/uiwriter9.cxx @@ -38,6 +38,8 @@ #include <swacorr.hxx> #include <sfx2/linkmgr.hxx> +#include <scriptinfo.hxx> +#include <txtfrm.hxx> #include <edtwin.hxx> #include <view.hxx> #include <wrtsh.hxx> @@ -1142,6 +1144,55 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf162195) xTables->getAnchor()->getString()); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf164140) +{ + createSwDoc("tdf164140.fodt"); + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + + SwTextFrame& pTextFrame + = dynamic_cast<SwTextFrame&>(*pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()); + const SwScriptInfo* pSI = pTextFrame.GetScriptInfo(); + + // Prior to editing, the three complete lines should be flagged as no-kashida: + auto stBeforeLines = pSI->GetNoKashidaLines(); + + CPPUNIT_ASSERT_EQUAL(size_t(4), stBeforeLines.size()); + auto stBeforeIt = stBeforeLines.begin(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), std::get<0>(*stBeforeIt)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(88), std::get<1>(*stBeforeIt)); + ++stBeforeIt; + CPPUNIT_ASSERT_EQUAL(sal_Int32(88), std::get<0>(*stBeforeIt)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(180), std::get<1>(*stBeforeIt)); + ++stBeforeIt; + CPPUNIT_ASSERT_EQUAL(sal_Int32(180), std::get<0>(*stBeforeIt)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(269), std::get<1>(*stBeforeIt)); + ++stBeforeIt; + CPPUNIT_ASSERT_EQUAL(sal_Int32(269), std::get<0>(*stBeforeIt)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(312), std::get<1>(*stBeforeIt)); + + // Insert text at the beginning of the document + pWrtShell->Insert(u"A"_ustr); + + // After editing, the three complete lines should still be flagged as no-kashida + auto stAfterLines = pSI->GetNoKashidaLines(); + + // Without the fix, this will be 2 + CPPUNIT_ASSERT_EQUAL(size_t(4), stAfterLines.size()); + + auto stAfterIt = stAfterLines.begin(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), std::get<0>(*stAfterIt)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(89), std::get<1>(*stAfterIt)); + ++stAfterIt; + CPPUNIT_ASSERT_EQUAL(sal_Int32(89), std::get<0>(*stAfterIt)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(181), std::get<1>(*stAfterIt)); + ++stAfterIt; + CPPUNIT_ASSERT_EQUAL(sal_Int32(181), std::get<0>(*stAfterIt)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(270), std::get<1>(*stAfterIt)); + ++stAfterIt; + CPPUNIT_ASSERT_EQUAL(sal_Int32(270), std::get<0>(*stAfterIt)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(313), std::get<1>(*stAfterIt)); +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); |