summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/source/core/text/itrform2.cxx10
-rw-r--r--sw/source/core/text/portxt.cxx6
-rw-r--r--vcl/source/gdi/impglyphitem.cxx9
3 files changed, 21 insertions, 4 deletions
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index b4256d85888f..893666e1108d 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -1419,8 +1419,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
@@ -1445,7 +1448,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 476dbf7aac77..d7c376de35ce 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -438,6 +438,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 300127de6b7a..184e9f819b5a 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 && pos > 0 && text[pos - 1] == nbSpace)