summaryrefslogtreecommitdiff
path: root/sw/qa
diff options
context:
space:
mode:
authorJonathan Clark <jonathan@libreoffice.org>2025-02-27 00:55:11 -0700
committerJonathan Clark <jonathan@libreoffice.org>2025-02-27 15:38:18 +0100
commitfac5695974d8a2197edba1e9f69f86621196cae1 (patch)
treeda3ba7521adbe90fa04941edc32f46e626a91079 /sw/qa
parent406afe11711df9fcabbc829fcff00aef2f44c1d9 (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.cxx4
-rw-r--r--sw/qa/extras/uiwriter/data/tdf164140.fodt117
-rw-r--r--sw/qa/extras/uiwriter/uiwriter9.cxx51
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();