diff options
author | Jonathan Clark <jonathan@libreoffice.org> | 2024-07-12 13:40:34 -0600 |
---|---|---|
committer | Adolfo Jayme Barrientos <fitojb@ubuntu.com> | 2024-09-04 18:16:38 +0200 |
commit | ef40759390de4eba93d0a1e9369fc8ba5c1ea534 (patch) | |
tree | 0f6ed26ced36087726c6a3a1aa349923f3b70980 | |
parent | 74a68f76bb116e348826bff912d52d8205ab92a3 (diff) |
tdf#92064 sw: Improve Tibetan layout performance
This change includes the following scalability improvements for
documents containing extremely long paragraphs:
- Reduces the size of layout contexts to account for line breaks.
- Disables a misbehaving glyph cache performance optimization for long
strings.
Change-Id: Ie9a3365076c0d112a7a655988d672a9f4609b42b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170420
Tested-by: Jenkins
Reviewed-by: Jonathan Clark <jonathan@libreoffice.org>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172858
Reviewed-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>
-rw-r--r-- | sw/source/core/text/itrform2.cxx | 10 | ||||
-rw-r--r-- | sw/source/core/text/portxt.cxx | 6 | ||||
-rw-r--r-- | vcl/source/gdi/impglyphitem.cxx | 9 |
3 files changed, 21 insertions, 4 deletions
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 71b78bc0914d..3673b46ba247 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -1418,8 +1418,11 @@ SwTextPortion *SwTextFormatter::NewTextPortion( SwTextFormatInfo &rInf ) if (!nCharWidthGuess) nCharWidthGuess = 1; auto nExpect = rInf.GetIdx() + TextFrameIndex(rInf.GetLineWidth() / nCharWidthGuess); - if (nExpect > rInf.GetIdx() && nNextChg > nExpect) - nNextChg = nExpect; + if (nExpect > rInf.GetIdx()) + { + nNextChg = std::min(nNextChg, nExpect); + nNextContext = std::min(nNextContext, nExpect); + } // we keep an invariant during method calls: // there are no portion ending characters like hard spaces @@ -1444,7 +1447,8 @@ SwTextPortion *SwTextFormatter::NewTextPortion( SwTextFormatInfo &rInf ) // for the first text portion in a paragraph, or for any successive // portions that are outside of the bounds of the previous context. if (!rInf.GetLayoutContext().has_value() - || rInf.GetLayoutContext()->m_nEnd <= rInf.GetIdx().get()) + || rInf.GetLayoutContext()->m_nBegin < rInf.GetLineStart().get() + || rInf.GetLayoutContext()->m_nEnd < nNextChg.get()) { // The layout context must terminate at special characters sal_Int32 nEnd = rInf.GetIdx().get(); diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx index ee39f156c24a..ec0303c0665c 100644 --- a/sw/source/core/text/portxt.cxx +++ b/sw/source/core/text/portxt.cxx @@ -445,6 +445,12 @@ bool SwTextPortion::Format_( SwTextFormatInfo &rInf ) SetLen( pGuess->BreakPos() - rInf.GetIdx() ); + // Clamp layout context to the end of the line + if(auto stClampedContext = GetLayoutContext(); stClampedContext.has_value()) { + stClampedContext->m_nEnd = pGuess->BreakPos().get(); + SetLayoutContext(stClampedContext); + } + OSL_ENSURE( pGuess->BreakStart() >= pGuess->FieldDiff(), "Trouble with expanded field portions during line break" ); TextFrameIndex const nRealStart = pGuess->BreakStart() - pGuess->FieldDiff(); diff --git a/vcl/source/gdi/impglyphitem.cxx b/vcl/source/gdi/impglyphitem.cxx index 1b40291736b7..946230a51762 100644 --- a/vcl/source/gdi/impglyphitem.cxx +++ b/vcl/source/gdi/impglyphitem.cxx @@ -364,6 +364,13 @@ const SalLayoutGlyphs* SalLayoutGlyphsCache::GetLayoutGlyphs( // part being underlined. Doing this for any two segments allows this optimization // even when the prefix of the string would use a different font. // TODO: Can those font differences be ignored? + + // Shaping performance seems to scale poorly with respect to string length. Certain + // writing systems involve extremely long strings (for example, Tibetan: tdf#92064). + // In such cases, this optimization would be a net loss, and must be disabled. + constexpr sal_Int32 nOptLengthThreshold = 20000; + bool bEnableOptimization = (text.getLength() < nOptLengthThreshold); + // Writer layouts tests enable SAL_NON_APPLICATION_FONT_USE=abort in order // to make PrintFontManager::Substitute() abort if font fallback happens. When // laying out the entire string the chance this happens increases (e.g. testAbi11870 @@ -374,7 +381,7 @@ const SalLayoutGlyphs* SalLayoutGlyphsCache::GetLayoutGlyphs( const char* pEnv = getenv("SAL_NON_APPLICATION_FONT_USE"); return pEnv && strcmp(pEnv, "abort") == 0; }(); - if (mLastSubstringKey.has_value() && !bAbortOnFontSubstitute) + if (bEnableOptimization && mLastSubstringKey.has_value() && !bAbortOnFontSubstitute) { sal_Int32 pos = nIndex; if (mLastSubstringKey->len < pos && text[pos - 1] == nbSpace) |