drawinglayer/source/processor2d/vclprocessor2d.cxx |    2 
 editeng/source/items/svxfont.cxx                   |    6 +-
 filter/source/svg/svgwriter.cxx                    |    3 -
 include/vcl/outdev.hxx                             |   25 +++++---
 sw/source/core/inc/drawfont.hxx                    |   36 ++++++++++++
 sw/source/core/text/frmform.cxx                    |   21 ++++---
 sw/source/core/text/guess.cxx                      |   45 ++++++++++-----
 sw/source/core/text/inftxt.cxx                     |   19 +++---
 sw/source/core/text/inftxt.hxx                     |   12 +++-
 sw/source/core/text/itrform2.cxx                   |    2 
 sw/source/core/text/itrpaint.cxx                   |    6 +-
 sw/source/core/text/porfld.cxx                     |    4 -
 sw/source/core/text/porlay.cxx                     |    3 -
 sw/source/core/text/porlay.hxx                     |   11 ++-
 sw/source/core/text/txtpaint.cxx                   |    7 --
 sw/source/core/text/txtpaint.hxx                   |   15 ++---
 sw/source/core/txtnode/fntcache.cxx                |   41 +++++++++++---
 toolkit/source/awt/vclxfont.cxx                    |    2 
 vcl/qa/cppunit/complextext.cxx                     |   60 ++++++++++++++-------
 vcl/qa/cppunit/text.cxx                            |   15 +++--
 vcl/source/filter/wmf/emfwr.cxx                    |    2 
 vcl/source/filter/wmf/wmfwr.cxx                    |    3 -
 vcl/source/outdev/text.cxx                         |   47 ++++++++++------
 vcl/source/text/textlayout.cxx                     |    7 +-
 24 files changed, 263 insertions(+), 131 deletions(-)

New commits:
commit 976b16b1c6ad6e6eaded7a9fb24388c4512e21e2
Author:     Jonathan Clark <jonat...@libreoffice.org>
AuthorDate: Fri Jun 7 02:36:22 2024 -0600
Commit:     Jonathan Clark <jonat...@libreoffice.org>
CommitDate: Mon Jun 10 17:11:32 2024 +0200

    tdf#152024 Diacritics cut off at top and bottom of paragraph
    
    This change fixes issues causing Writer to clip paragraphs at the ascent
    of the top line, and descent of the last line, of a paragraph. This
    issue caused certain diacritics to render incompletely, or not at all.
    
    Change-Id: I99a3a25335f8b1d798fc8a55ff42d5c78749fca4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168557
    Tested-by: Jenkins
    Reviewed-by: Jonathan Clark <jonat...@libreoffice.org>

diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index e0a090cf9ecd..45825a2a477b 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -337,7 +337,7 @@ void 
VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(
                 tools::Long nWidthToFill = rTextCandidate.getWidthToFill();
 
                 tools::Long nWidth = basegfx::fround<tools::Long>(
-                    mpOutputDevice->GetTextArray(rTextCandidate.getText(), 
&aDXArray, 0, 1));
+                    mpOutputDevice->GetTextArray(rTextCandidate.getText(), 
&aDXArray, 0, 1).nWidth);
                 sal_Int32 nChars = 2;
                 if (nWidth)
                     nChars = nWidthToFill / nWidth;
diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx
index 253c78f8dea4..2df18feb449f 100644
--- a/editeng/source/items/svxfont.cxx
+++ b/editeng/source/items/svxfont.cxx
@@ -38,7 +38,8 @@ static tools::Long GetTextArray( const OutputDevice* pOut, 
const OUString& rStr,
 
 {
     const SalLayoutGlyphs* layoutGlyphs = 
SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOut, rStr, nIndex, nLen);
-    return basegfx::fround<tools::Long>(pOut->GetTextArray( rStr, pDXAry, 
nIndex, nLen, true, nullptr, layoutGlyphs));
+    return basegfx::fround<tools::Long>(
+        pOut->GetTextArray(rStr, pDXAry, nIndex, nLen, true, nullptr, 
layoutGlyphs).nWidth);
 }
 
 SvxFont::SvxFont()
@@ -719,7 +720,8 @@ void SvxDoGetCapitalSize::Do( const OUString &_rTxt, const 
sal_Int32 _nIdx,
     if (pDXAry)
     {
         KernArray aKernArray;
-        
aPartSize.setWidth(basegfx::fround<tools::Long>(pOut->GetTextArray(_rTxt, 
&aKernArray, _nIdx, _nLen)));
+        aPartSize.setWidth(basegfx::fround<tools::Long>(
+            pOut->GetTextArray(_rTxt, &aKernArray, _nIdx, _nLen).nWidth));
         assert(pDXAry->get_factor() == aKernArray.get_factor());
         auto& dest = pDXAry->get_subunit_array();
         sal_Int32 nStart = dest.empty() ? 0 : dest.back();
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index e4c885cd6ca4..57a039f32a18 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -2679,7 +2679,8 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, 
const OUString& rText,
     }
     else
     {
-        aNormSize = 
Size(basegfx::fround<tools::Long>(mpVDev->GetTextArray(rText, &aTmpArray)), 0);
+        aNormSize
+            = Size(basegfx::fround<tools::Long>(mpVDev->GetTextArray(rText, 
&aTmpArray).nWidth), 0);
     }
 
     // if text is rotated, set transform matrix at new g element
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 347d5bb82226..2fddb3c3f24a 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -160,6 +160,12 @@ class OutputDevice;
 
 namespace vcl {
     typedef OutputDevice RenderContext;
+
+    struct TextArrayMetrics
+    {
+        std::optional<tools::Rectangle> aBounds;
+        double nWidth = 0.0;
+    };
 }
 
 VCL_DLLPUBLIC void InvertFocusRect(vcl::RenderContext& rRenderContext, const 
tools::Rectangle& rRect);
@@ -1059,20 +1065,23 @@ public:
                                                sal_Int32 nLen,
                                                SalLayoutFlags flags = 
SalLayoutFlags::NONE,
                                                const SalLayoutGlyphs* 
pLayoutCache = nullptr);
-    double                      GetTextArray( const OUString& rStr, KernArray* 
pDXAry,
-                                              sal_Int32 nIndex = 0, sal_Int32 
nLen = -1, bool bCaret = false,
-                                              vcl::text::TextLayoutCache 
const* = nullptr,
-                                              SalLayoutGlyphs const*const 
pLayoutCache = nullptr) const;
+    vcl::TextArrayMetrics GetTextArray(const OUString& rStr, KernArray* pDXAry,
+                                       sal_Int32 nIndex = 0, sal_Int32 nLen = 
-1,
+                                       bool bCaret = false,
+                                       vcl::text::TextLayoutCache const* = 
nullptr,
+                                       SalLayoutGlyphs const* const 
pLayoutCache = nullptr) const;
 
     void DrawPartialTextArray(const Point& rStartPt, const OUString& rStr, 
KernArraySpan aKernArray,
                               std::span<const sal_Bool> pKashidaAry, sal_Int32 
nIndex,
                               sal_Int32 nLen, sal_Int32 nPartIndex, sal_Int32 
nPartLen,
                               SalLayoutFlags flags = SalLayoutFlags::NONE,
                               const SalLayoutGlyphs* pLayoutCache = nullptr);
-    double GetPartialTextArray(const OUString& rStr, KernArray* pDXAry, 
sal_Int32 nIndex,
-                               sal_Int32 nLen, sal_Int32 nPartIndex, sal_Int32 
nPartLen,
-                               bool bCaret = false, const 
vcl::text::TextLayoutCache* = nullptr,
-                               const SalLayoutGlyphs* pLayoutCache = nullptr) 
const;
+    vcl::TextArrayMetrics GetPartialTextArray(const OUString& rStr, KernArray* 
pDXAry,
+                                              sal_Int32 nIndex, sal_Int32 nLen,
+                                              sal_Int32 nPartIndex, sal_Int32 
nPartLen,
+                                              bool bCaret = false,
+                                              const 
vcl::text::TextLayoutCache* = nullptr,
+                                              const SalLayoutGlyphs* 
pLayoutCache = nullptr) const;
 
     SAL_DLLPRIVATE void         GetCaretPositions( const OUString&, KernArray& 
rCaretXArray,
                                               sal_Int32 nIndex, sal_Int32 nLen,
diff --git a/sw/source/core/inc/drawfont.hxx b/sw/source/core/inc/drawfont.hxx
index 646ab21c60b7..c262cb931581 100644
--- a/sw/source/core/inc/drawfont.hxx
+++ b/sw/source/core/inc/drawfont.hxx
@@ -60,6 +60,8 @@ class SW_DLLPUBLIC SwDrawTextInfo
     SwUnderlineFont* m_pUnderFnt = nullptr;
     TextFrameIndex* m_pHyphPos = nullptr;
     tools::Long m_nKanaDiff = 0;
+    SwTwips m_nExtraAscent = 0;
+    SwTwips m_nExtraDescent = 0;
     TextFrameIndex m_nIdx;
     TextFrameIndex m_nLen;
     TextFrameIndex m_nMeasureLen = TextFrameIndex{ COMPLETE_STRING };
@@ -105,6 +107,8 @@ class SW_DLLPUBLIC SwDrawTextInfo
     bool m_bNumberOfBlanks : 1 = false;
     bool m_bUppr : 1 = false;
     bool m_bDrawSp : 1 = false;
+    bool m_bExtraAscent : 1 = false;
+    bool m_bExtraDescent : 1 = false;
 #endif
 
 public:
@@ -271,6 +275,22 @@ public:
         return m_nKanaDiff;
     }
 
+    SwTwips GetExtraAscent() const
+    {
+#ifdef DBG_UTIL
+        OSL_ENSURE(m_bExtraAscent, "DrawTextInfo: Undefined extra ascent");
+#endif
+        return m_nExtraAscent;
+    }
+
+    SwTwips GetExtraDescent() const
+    {
+#ifdef DBG_UTIL
+        OSL_ENSURE(m_bExtraDescent, "DrawTextInfo: Undefined extra descent");
+#endif
+        return m_nExtraDescent;
+    }
+
     sal_uInt16 GetWidth() const
     {
         return m_nWidth;
@@ -490,6 +510,22 @@ public:
 #endif
     }
 
+    void SetExtraAscent(SwTwips nNew)
+    {
+        m_nExtraAscent = nNew;
+#ifdef DBG_UTIL
+        m_bExtraAscent = true;
+#endif
+    }
+
+    void SetExtraDescent(SwTwips nNew)
+    {
+        m_nExtraDescent = nNew;
+#ifdef DBG_UTIL
+        m_bExtraDescent = true;
+#endif
+    }
+
     void SetWidth( sal_uInt16 nNew )
     {
         m_nWidth = nNew;
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index 4e2caf27b276..0d9a8c7ae9ff 100644
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -1465,13 +1465,20 @@ bool SwTextFrame::FormatLine( SwTextFormatter &rLine, 
const bool bPrev )
             rRepaint.SetRightOfst( nRght );
 
         // Finally we enlarge the repaint rectangle if we found an underscore
-        // within our line. 40 Twips should be enough
-        const bool bHasUnderscore =
-                ( rLine.GetInfo().GetUnderScorePos() < nNewStart );
-        if ( bHasUnderscore || rLine.GetCurr()->HasUnderscore() )
-            rRepaint.Bottom( rRepaint.Bottom() + 40 );
-
-        const_cast<SwLineLayout*>(rLine.GetCurr())->SetUnderscore( 
bHasUnderscore );
+        // or another glyph extending beyond the line height within the line.
+        auto nBaseAscent = pNew->GetAscent();
+        auto nMaxExtraAscent
+            = std::max({ SwTwips{ 0 }, rLine.GetInfo().GetExtraAscent() - 
nBaseAscent,
+                         rLine.GetCurr()->GetExtraAscent() });
+        rRepaint.Top(rRepaint.Top() - nMaxExtraAscent);
+        
const_cast<SwLineLayout*>(rLine.GetCurr())->SetExtraAscent(nMaxExtraAscent);
+
+        auto nBaseDescent = pNew->Height() - pNew->GetAscent();
+        auto nMaxExtraDescent
+            = std::max({ SwTwips{ 0 }, rLine.GetInfo().GetExtraDescent() - 
nBaseDescent,
+                         rLine.GetCurr()->GetExtraDescent() });
+        rRepaint.Bottom(rRepaint.Bottom() + nMaxExtraDescent);
+        
const_cast<SwLineLayout*>(rLine.GetCurr())->SetExtraDescent(nMaxExtraDescent);
     }
 
     // Calculating the good ol' nDelta
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
index c476de7110cc..f49f6fccd3d2 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -79,6 +79,7 @@ bool hasBlanksInLine(const SwTextFormatInfo& rInf, 
TextFrameIndex end)
 bool maybeAdjustPositionsForBlockAdjust(TextFrameIndex& rCutPos, 
TextFrameIndex& rBreakPos,
                                         TextFrameIndex& rBreakStart, SwTwips& 
rBreakWidth,
                                         SwTwips& rExtraBlankWidth, 
tools::Long& rMaxSizeDiff,
+                                        SwTwips& rExtraAscent, SwTwips& 
rExtraDescent,
                                         const SwTextFormatInfo& rInf, const 
SwScriptInfo& rSI,
                                         sal_uInt16 maxComp,
                                         
std::optional<SwLinePortionLayoutContext> nLayoutContext)
@@ -141,9 +142,11 @@ bool maybeAdjustPositionsForBlockAdjust(TextFrameIndex& 
rCutPos, TextFrameIndex&
     rBreakPos = breakPos;
 
     rInf.GetTextSize(&rSI, rInf.GetIdx(), breakPos - rInf.GetIdx(), 
nLayoutContext, maxComp,
-                     rBreakWidth, rMaxSizeDiff, rInf.GetCachedVclData().get());
+                     rBreakWidth, rMaxSizeDiff, rExtraAscent, rExtraDescent,
+                     rInf.GetCachedVclData().get());
     rInf.GetTextSize(&rSI, breakPos, rBreakStart - breakPos, nLayoutContext, 
maxComp,
-                     rExtraBlankWidth, rMaxSizeDiff, 
rInf.GetCachedVclData().get());
+                     rExtraBlankWidth, rMaxSizeDiff, rExtraAscent, 
rExtraDescent,
+                     rInf.GetCachedVclData().get());
 
     return false; // require SwHolePortion creation
 }
@@ -168,6 +171,8 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
     OSL_ENSURE( nPorHeight, "+SwTextGuess::Guess: no height" );
 
     tools::Long nMaxSizeDiff;
+    SwTwips nExtraAscent = 0;
+    SwTwips nExtraDescent = 0;
 
     const SwScriptInfo& rSI = rInf.GetParaPortion()->GetScriptInfo();
 
@@ -249,17 +254,17 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
     {
         // call GetTextSize with maximum compression (for kanas)
         rInf.GetTextSize(&rSI, rInf.GetIdx(), nMaxLen, 
rInf.GetLayoutContext(), nMaxComp,
-                         m_nBreakWidth, nMaxSizeDiff);
+                         m_nBreakWidth, nMaxSizeDiff, nExtraAscent, 
nExtraDescent);
 
         if ( ( m_nBreakWidth <= nLineWidth ) || ( bUnbreakableNumberings && 
rPor.IsNumberPortion() ) )
         {
             // portion fits to line
             m_nCutPos = rInf.GetIdx() + nMaxLen;
             bool bRet = rPor.InFieldGrp()
-                        || maybeAdjustPositionsForBlockAdjust(m_nCutPos, 
m_nBreakPos, m_nBreakStart,
-                                                              m_nBreakWidth, 
m_nExtraBlankWidth,
-                                                              nMaxSizeDiff, 
rInf, rSI, nMaxComp,
-                                                              
rInf.GetLayoutContext());
+                        || maybeAdjustPositionsForBlockAdjust(
+                            m_nCutPos, m_nBreakPos, m_nBreakStart, 
m_nBreakWidth,
+                            m_nExtraBlankWidth, nMaxSizeDiff, nExtraAscent, 
nExtraDescent, rInf,
+                            rSI, nMaxComp, rInf.GetLayoutContext());
             if( nItalic &&
                 (m_nCutPos >= TextFrameIndex(rInf.GetText().getLength()) ||
                   // #i48035# Needed for CalcFitToContent
@@ -271,6 +276,9 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
             if ( nMaxSizeDiff )
                 rInf.SetMaxWidthDiff( &rPor, nMaxSizeDiff );
 
+            rInf.SetExtraAscent(nExtraAscent);
+            rInf.SetExtraDescent(nExtraDescent);
+
             m_nBreakWidth += nLeftRightBorderSpace;
 
             return bRet;
@@ -422,7 +430,7 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
         {
             SwTwips nMinSize;
             rInf.GetTextSize(&rSI, rInf.GetIdx(), m_nCutPos - rInf.GetIdx(), 
std::nullopt, nMaxComp,
-                             nMinSize, nMaxSizeDiff);
+                             nMinSize, nMaxSizeDiff, nExtraAscent, 
nExtraDescent);
             OSL_ENSURE( nMinSize <= nLineWidth, "What a Guess!!!" );
         }
 #endif
@@ -433,17 +441,17 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
         // second check if everything fits to line
         m_nCutPos = m_nBreakPos = rInf.GetIdx() + nMaxLen - TextFrameIndex(1);
         rInf.GetTextSize(&rSI, rInf.GetIdx(), nMaxLen, 
rInf.GetLayoutContext(), nMaxComp,
-                         m_nBreakWidth, nMaxSizeDiff);
+                         m_nBreakWidth, nMaxSizeDiff, nExtraAscent, 
nExtraDescent);
 
         // The following comparison should always give true, otherwise
         // there likely has been a pixel rounding error in GetTextBreak
         if ( m_nBreakWidth <= nLineWidth )
         {
             bool bRet = rPor.InFieldGrp()
-                        || maybeAdjustPositionsForBlockAdjust(m_nCutPos, 
m_nBreakPos, m_nBreakStart,
-                                                              m_nBreakWidth, 
m_nExtraBlankWidth,
-                                                              nMaxSizeDiff, 
rInf, rSI, nMaxComp,
-                                                              
rInf.GetLayoutContext());
+                        || maybeAdjustPositionsForBlockAdjust(
+                            m_nCutPos, m_nBreakPos, m_nBreakStart, 
m_nBreakWidth,
+                            m_nExtraBlankWidth, nMaxSizeDiff, nExtraAscent, 
nExtraDescent, rInf,
+                            rSI, nMaxComp, rInf.GetLayoutContext());
 
             if (nItalic && (m_nBreakPos + TextFrameIndex(1)) >= 
TextFrameIndex(rInf.GetText().getLength()))
                 m_nBreakWidth += nItalic;
@@ -452,6 +460,9 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
             if ( nMaxSizeDiff )
                 rInf.SetMaxWidthDiff( &rPor, nMaxSizeDiff );
 
+            rInf.SetExtraAscent(nExtraAscent);
+            rInf.SetExtraDescent(nExtraDescent);
+
             m_nBreakWidth += nLeftRightBorderSpace;
 
             return bRet;
@@ -736,12 +747,15 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
     if( nPorLen )
     {
         rInf.GetTextSize(&rSI, rInf.GetIdx(), nPorLen, std::nullopt, nMaxComp, 
m_nBreakWidth,
-                         nMaxSizeDiff, rInf.GetCachedVclData().get());
+                         nMaxSizeDiff, nExtraAscent, nExtraDescent, 
rInf.GetCachedVclData().get());
 
         // save maximum width for later use
         if ( nMaxSizeDiff )
             rInf.SetMaxWidthDiff( &rPor, nMaxSizeDiff );
 
+        rInf.SetExtraAscent(nExtraAscent);
+        rInf.SetExtraDescent(nExtraDescent);
+
         m_nBreakWidth += nItalic + nLeftRightBorderSpace;
     }
     else
@@ -751,7 +765,8 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
     {
         rInf.GetTextSize(&rSI, rInf.GetIdx() + nPorLen,
                          m_nBreakStart - rInf.GetIdx() - nPorLen - 
m_nFieldDiff, std::nullopt,
-                         nMaxComp, m_nExtraBlankWidth, nMaxSizeDiff, 
rInf.GetCachedVclData().get());
+                         nMaxComp, m_nExtraBlankWidth, nMaxSizeDiff, 
nExtraAscent, nExtraDescent,
+                         rInf.GetCachedVclData().get());
     }
 
     if( m_pHanging )
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 40b113fa41da..25bd4578e025 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -86,7 +86,6 @@ using namespace ::com::sun::star::linguistic2;
 using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::beans;
 
-#define CHAR_UNDERSCORE u'_'
 #define CHAR_LEFT_ARROW u'\x25C0'
 #define CHAR_RIGHT_ARROW u'\x25B6'
 #define CHAR_TAB u'\x2192'
@@ -438,7 +437,8 @@ void SwTextSizeInfo::GetTextSize(const SwScriptInfo* pSI, 
const TextFrameIndex n
                                  const TextFrameIndex nLength,
                                  std::optional<SwLinePortionLayoutContext> 
nLayoutContext,
                                  const sal_uInt16 nComp, SwTwips& nMinSize,
-                                 tools::Long& nMaxSizeDiff,
+                                 tools::Long& nMaxSizeDiff, SwTwips& 
nExtraAscent,
+                                 SwTwips& nExtraDescent,
                                  vcl::text::TextLayoutCache const* const 
pCache) const
 {
     SwDrawTextInfo aDrawInf(m_pVsh, *m_pOut, pSI, *m_pText, nIndex, nLength, 
nLayoutContext, 0,
@@ -449,6 +449,8 @@ void SwTextSizeInfo::GetTextSize(const SwScriptInfo* pSI, 
const TextFrameIndex n
     aDrawInf.SetKanaComp( nComp );
     SwPosSize aSize( m_pFnt->GetTextSize_( aDrawInf ) );
     nMaxSizeDiff = aDrawInf.GetKanaDiff();
+    nExtraAscent = aDrawInf.GetExtraAscent();
+    nExtraDescent = aDrawInf.GetExtraDescent();
     nMinSize = aSize.Width();
 }
 
@@ -1624,6 +1626,8 @@ void SwTextFormatInfo::CtorInitTextFormatInfo( 
OutputDevice* pRenderContext, SwT
     m_nFirst = 0;
     m_nRealWidth = 0;
     m_nForcedLeftMargin = 0;
+    m_nExtraAscent = 0;
+    m_nExtraDescent = 0;
     m_pRest = nullptr;
     m_nLineHeight = 0;
     m_nLineNetHeight = 0;
@@ -1722,8 +1726,9 @@ void SwTextFormatInfo::Init()
     m_cTabDecimal = 0;
     m_nWidth = m_nRealWidth;
     m_nForcedLeftMargin = 0;
+    m_nExtraAscent = 0;
+    m_nExtraDescent = 0;
     m_nSoftHyphPos = TextFrameIndex(0);
-    m_nUnderScorePos = TextFrameIndex(COMPLETE_STRING);
     m_nLastBookmarkPos = TextFrameIndex(-1);
     m_cHookChar = 0;
     SetIdx(TextFrameIndex(0));
@@ -1756,7 +1761,6 @@ SwTextFormatInfo::SwTextFormatInfo( const 
SwTextFormatInfo& rInf,
     m_pLastTab(nullptr),
     m_nSoftHyphPos(TextFrameIndex(0)),
     m_nLineStart(rInf.GetIdx()),
-    m_nUnderScorePos(TextFrameIndex(COMPLETE_STRING)),
     m_nLeft(rInf.m_nLeft),
     m_nRight(rInf.m_nRight),
     m_nFirst(rInf.m_nLeft),
@@ -1765,6 +1769,8 @@ SwTextFormatInfo::SwTextFormatInfo( const 
SwTextFormatInfo& rInf,
     m_nLineHeight(0),
     m_nLineNetHeight(0),
     m_nForcedLeftMargin(0),
+    m_nExtraAscent(0),
+    m_nExtraDescent(0),
     m_bFull(false),
     m_bFootnoteDone(true),
     m_bErgoDone(true),
@@ -1875,11 +1881,6 @@ TextFrameIndex 
SwTextFormatInfo::ScanPortionEnd(TextFrameIndex const nStart,
             m_cHookChar = cPos;
             return i;
 
-        case CHAR_UNDERSCORE:
-            if (TextFrameIndex(COMPLETE_STRING) == m_nUnderScorePos)
-                m_nUnderScorePos = i;
-            break;
-
         default:
             if ( cTabDec )
             {
diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx
index 4cc49a0e3e57..4a79177366c9 100644
--- a/sw/source/core/text/inftxt.hxx
+++ b/sw/source/core/text/inftxt.hxx
@@ -254,6 +254,7 @@ public:
     void GetTextSize(const SwScriptInfo* pSI, TextFrameIndex nIdx, 
TextFrameIndex nLen,
                      std::optional<SwLinePortionLayoutContext> nLayoutContext,
                      const sal_uInt16 nComp, SwTwips& nMinSize, tools::Long& 
nMaxSizeDiff,
+                     SwTwips& nExtraAscent, SwTwips& nExtraDescent,
                      vcl::text::TextLayoutCache const* = nullptr) const;
     inline SwPosSize GetTextSize(const SwScriptInfo* pSI, TextFrameIndex nIdx,
                                  TextFrameIndex nLen) const;
@@ -493,7 +494,6 @@ class SwTextFormatInfo : public SwTextPaintInfo
 
     TextFrameIndex m_nSoftHyphPos;   ///< SoftHyphPos for Hyphenation
     TextFrameIndex m_nLineStart;     ///< Current line start in rText
-    TextFrameIndex m_nUnderScorePos; ///< enlarge repaint if underscore has 
been found
     TextFrameIndex m_nLastBookmarkPos; ///< need to check for bookmarks at 
every portion
     // #i34348# Changed type from sal_uInt16 to SwTwips
     SwTwips m_nLeft;              // Left margin
@@ -506,6 +506,8 @@ class SwTextFormatInfo : public SwTextPaintInfo
     SwTwips m_nLineHeight;     // Final height after CalcLine
     SwTwips m_nLineNetHeight; // line height without spacing
     SwTwips m_nForcedLeftMargin; // Shift of left margin due to frame
+    SwTwips m_nExtraAscent = 0; // Enlarge clipping area for glyphs above the 
line height
+    SwTwips m_nExtraDescent = 0; // Enlarge clipping area for glyphs below the 
line height
 
     bool m_bFull : 1;             // Line is full
     bool m_bFootnoteDone : 1;          // Footnote already formatted
@@ -678,8 +680,12 @@ public:
 
     // Should the hyphenate helper be discarded?
     bool IsHyphenate() const;
-    TextFrameIndex GetUnderScorePos() const { return m_nUnderScorePos; }
-    void SetUnderScorePos(TextFrameIndex const nNew) { m_nUnderScorePos = 
nNew; }
+
+    SwTwips GetExtraAscent() const { return m_nExtraAscent; }
+    void SetExtraAscent(SwTwips nNew) { m_nExtraAscent = 
std::max(m_nExtraAscent, nNew); }
+
+    SwTwips GetExtraDescent() const { return m_nExtraDescent; }
+    void SetExtraDescent(SwTwips nNew) { m_nExtraDescent = 
std::max(m_nExtraDescent, nNew); }
 
     // Calls HyphenateWord() of Hyphenator
     css::uno::Reference< css::linguistic2::XHyphenatedWord >
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 9d8e9ae0b77a..430e8d9aa778 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -177,7 +177,6 @@ SwLinePortion *SwTextFormatter::Underflow( SwTextFormatInfo 
&rInf )
     // Can be seen in 8081.sdw, if you enter text in the first line
 
     TextFrameIndex const nSoftHyphPos = rInf.GetSoftHyphPos();
-    TextFrameIndex const nUnderScorePos = rInf.GetUnderScorePos();
 
     // Save flys and set to 0, or else segmentation fault
     // Not ClearFly(rInf) !
@@ -190,7 +189,6 @@ SwLinePortion *SwTextFormatter::Underflow( SwTextFormatInfo 
&rInf )
     // Truncate()
     rInf.SetUnderflow(nullptr);
     rInf.SetSoftHyphPos( nSoftHyphPos );
-    rInf.SetUnderScorePos( nUnderScorePos );
     rInf.SetPaintOfst( GetLeftMargin() );
 
     // We look for the portion with the under-flow position
diff --git a/sw/source/core/text/itrpaint.cxx b/sw/source/core/text/itrpaint.cxx
index f02beed8ce5b..2a19650acb92 100644
--- a/sw/source/core/text/itrpaint.cxx
+++ b/sw/source/core/text/itrpaint.cxx
@@ -222,7 +222,7 @@ void SwTextPainter::DrawTextLine( const SwRect &rPaint, 
SwSaveClip &rClip,
             GetInfo().GetPos().Y() + nTmpHeight > rPaint.Top() + 
rPaint.Height() )
         {
             bClip = false;
-            rClip.ChgClip( rPaint, m_pFrame, m_pCurr->HasUnderscore() );
+            rClip.ChgClip(rPaint, m_pFrame, m_pCurr->GetExtraAscent(), 
m_pCurr->GetExtraDescent());
         }
 #if OSL_DEBUG_LEVEL > 1
         static bool bClipAlways = false;
@@ -255,7 +255,7 @@ void SwTextPainter::DrawTextLine( const SwRect &rPaint, 
SwSaveClip &rClip,
         // tdf#117448 at small fixed line height, enlarge clipping area in 
table cells
         // to show previously clipped text content on the area of paragraph 
margins
         if ( rFrame.IsInTab() )
-            rClip.ChgClip( aLineRect, m_pFrame, false, rFrame.GetTopMargin(), 
rFrame.GetBottomMargin() );
+            rClip.ChgClip(aLineRect, m_pFrame, rFrame.GetTopMargin(), 
rFrame.GetBottomMargin());
         else
             rClip.ChgClip( aLineRect, m_pFrame );
         bClip = false;
@@ -377,7 +377,7 @@ void SwTextPainter::DrawTextLine( const SwRect &rPaint, 
SwSaveClip &rClip,
             GetInfo().X() + pPor->Width() + ( pPor->Height() / 2 ) > nMaxRight 
)
         {
             bClip = false;
-            rClip.ChgClip( rPaint, m_pFrame, m_pCurr->HasUnderscore() );
+            rClip.ChgClip(rPaint, m_pFrame, m_pCurr->GetExtraAscent(), 
m_pCurr->GetExtraDescent());
         }
 
         // Portions, which lay "below" the text like post-its
diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx
index 6e8cfa4a3770..459486b99ba5 100644
--- a/sw/source/core/text/porfld.cxx
+++ b/sw/source/core/text/porfld.cxx
@@ -337,10 +337,6 @@ bool SwFieldPortion::Format( SwTextFormatInfo &rInf )
         }
         rInf.SetLen( nFullLen );
 
-        if (TextFrameIndex(COMPLETE_STRING) != rInf.GetUnderScorePos() &&
-             rInf.GetUnderScorePos() > rInf.GetIdx() )
-             rInf.SetUnderScorePos( rInf.GetIdx() );
-
         if( m_pFont )
             m_pFont->AllocFontCacheId( rInf.GetVsh(), m_pFont->GetActual() );
 
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 44f709eec1f1..bb33c11bf8b4 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -844,8 +844,7 @@ void SwLineLayout::ResetFlags()
 SwLineLayout::SwLineLayout()
     : m_pNext( nullptr ),
       m_nRealHeight( 0 ),
-      m_nTextHeight( 0 ),
-      m_bUnderscore( false )
+      m_nTextHeight( 0 )
 {
     ResetFlags();
     SetWhichPor( PortionType::Lay );
diff --git a/sw/source/core/text/porlay.hxx b/sw/source/core/text/porlay.hxx
index fe8aeb861e50..3d0ce27e3884 100644
--- a/sw/source/core/text/porlay.hxx
+++ b/sw/source/core/text/porlay.hxx
@@ -83,6 +83,8 @@ private:
     std::unique_ptr<std::deque<sal_uInt16>> m_pKanaComp;  // Used for Kana 
compression
     SwTwips m_nRealHeight;             // The height resulting from line 
spacing and register
     SwTwips m_nTextHeight;             // The max height of all non-FlyCnt 
portions in this Line
+    SwTwips m_nExtraAscent = 0;
+    SwTwips m_nExtraDescent = 0;
     bool m_bFormatAdj : 1;
     bool m_bDummy     : 1;
     bool m_bEndHyph   : 1;
@@ -97,7 +99,6 @@ private:
     bool m_bRedlineEnd: 1; // Redlining for paragraph mark: tracked change at 
the end
     bool m_bForcedLeftMargin : 1; // Left adjustment moved by the Fly
     bool m_bHanging : 1; // Contains a hanging portion in the margin
-    bool m_bUnderscore : 1;
 
     enum RedlineType m_eRedlineEnd; // redline type of pilcrow and line break 
symbols
 
@@ -146,8 +147,6 @@ public:
     bool HasForcedLeftMargin() const { return m_bForcedLeftMargin; }
     void SetHanging( const bool bNew ) { m_bHanging = bNew; }
     bool IsHanging() const { return m_bHanging; }
-    void SetUnderscore( const bool bNew ) { m_bUnderscore = bNew; }
-    bool HasUnderscore() const { return m_bUnderscore; }
 
     // Respecting empty dummy lines
     void SetDummy( const bool bNew ) { m_bDummy = bNew; }
@@ -173,6 +172,12 @@ public:
 
     SwTwips GetTextHeight() const { return m_nTextHeight; }
 
+    void SetExtraAscent(SwTwips nNew) { m_nExtraAscent = nNew; }
+    SwTwips GetExtraAscent() const { return m_nExtraAscent; }
+
+    void SetExtraDescent(SwTwips nNew) { m_nExtraDescent = nNew; }
+    SwTwips GetExtraDescent() const { return m_nExtraDescent; }
+
     // Creates the glue chain for short lines
     SwMarginPortion *CalcLeftMargin();
 
diff --git a/sw/source/core/text/txtpaint.cxx b/sw/source/core/text/txtpaint.cxx
index ccd9647bd99c..5b05b413fab9 100644
--- a/sw/source/core/text/txtpaint.cxx
+++ b/sw/source/core/text/txtpaint.cxx
@@ -41,7 +41,6 @@ SwSaveClip::~SwSaveClip()
 }
 
 void SwSaveClip::ChgClip_( const SwRect &rRect, const SwTextFrame* pFrame,
-                           bool bEnlargeRect,
                            sal_Int32 nEnlargeTop,
                            sal_Int32 nEnlargeBottom )
 {
@@ -74,12 +73,6 @@ void SwSaveClip::ChgClip_( const SwRect &rRect, const 
SwTextFrame* pFrame,
     {
         tools::Rectangle aRect( rRect.SVRect() );
 
-        // Having underscores in our line, we enlarged the repaint area
-        // (see frmform.cxx) because for some fonts it could be too small.
-        // Consequently, we have to enlarge the clipping rectangle as well.
-        if ( bEnlargeRect && ! bVertical )
-            aRect.AdjustBottom(40 );
-
         // enlarge clip for paragraph margins at small fixed line height
         if ( nEnlargeTop > 0 )
             aRect.AdjustTop( -nEnlargeTop );
diff --git a/sw/source/core/text/txtpaint.hxx b/sw/source/core/text/txtpaint.hxx
index 1f9700af4c96..3554a2421415 100644
--- a/sw/source/core/text/txtpaint.hxx
+++ b/sw/source/core/text/txtpaint.hxx
@@ -32,7 +32,6 @@ class SwSaveClip final
 
     VclPtr<OutputDevice> m_pOut;
     void ChgClip_( const SwRect &rRect, const SwTextFrame* pFrame,
-                   bool bEnlargeRect,
                    sal_Int32 nEnlargeTop,
                    sal_Int32 nEnlargeBottom );
 public:
@@ -44,12 +43,14 @@ public:
     }
 
     ~SwSaveClip();
-    void ChgClip( const SwRect &rRect, const SwTextFrame* pFrame = nullptr,
-                         bool bEnlargeRect = false,
-                         sal_Int32 nEnlargeTop = 0,
-                         sal_Int32 nEnlargeBottom = 0)
-             { if( m_pOut ) ChgClip_( rRect, pFrame,
-                         bEnlargeRect, nEnlargeTop, nEnlargeBottom ); }
+    void ChgClip(const SwRect& rRect, const SwTextFrame* pFrame = nullptr,
+                 sal_Int32 nEnlargeTop = 0, sal_Int32 nEnlargeBottom = 0)
+    {
+        if (m_pOut)
+        {
+            ChgClip_(rRect, pFrame, nEnlargeTop, nEnlargeBottom);
+        }
+    }
     bool IsOn()  const { return m_bOn; }
     bool IsChg() const { return m_bChg; }
 };
diff --git a/sw/source/core/txtnode/fntcache.cxx 
b/sw/source/core/txtnode/fntcache.cxx
index fd42378b1bdc..52a9e71dff1d 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -745,9 +745,12 @@ static void lcl_DrawLineForWrongListData(
 static void GetTextArray(const OutputDevice& rDevice, const OUString& rStr, 
KernArray& rDXAry,
                          sal_Int32 nIndex, sal_Int32 nLen,
                          std::optional<SwLinePortionLayoutContext> 
nLayoutContext,
+                         SwTwips* nMaxAscent = nullptr, SwTwips* nMaxDescent = 
nullptr,
                          bool bCaret = false,
                          const vcl::text::TextLayoutCache* layoutCache = 
nullptr)
 {
+    vcl::TextArrayMetrics stMetrics;
+
     if (nLayoutContext.has_value())
     {
         auto nStrEnd = nIndex + nLen;
@@ -757,14 +760,28 @@ static void GetTextArray(const OutputDevice& rDevice, 
const OUString& rStr, Kern
 
         const SalLayoutGlyphs* pLayoutCache = 
SalLayoutGlyphsCache::self()->GetLayoutGlyphs(
             &rDevice, rStr, nContextBegin, nContextLen, nIndex, nIndex + nLen, 
0, layoutCache);
-        rDevice.GetPartialTextArray(rStr, &rDXAry, nContextBegin, nContextLen, 
nIndex, nLen, bCaret,
-                                    layoutCache, pLayoutCache);
+        stMetrics = rDevice.GetPartialTextArray(rStr, &rDXAry, nContextBegin, 
nContextLen, nIndex,
+                                                nLen, bCaret, layoutCache, 
pLayoutCache);
     }
     else
     {
         const SalLayoutGlyphs* pLayoutCache = 
SalLayoutGlyphsCache::self()->GetLayoutGlyphs(
             &rDevice, rStr, nIndex, nLen, 0, layoutCache);
-        rDevice.GetTextArray(rStr, &rDXAry, nIndex, nLen, bCaret, layoutCache, 
pLayoutCache);
+        stMetrics
+            = rDevice.GetTextArray(rStr, &rDXAry, nIndex, nLen, bCaret, 
layoutCache, pLayoutCache);
+    }
+
+    if (stMetrics.aBounds.has_value())
+    {
+        if (nMaxAscent)
+        {
+            *nMaxAscent = 
static_cast<SwTwips>(std::ceil(-stMetrics.aBounds->Top()));
+        }
+
+        if (nMaxDescent)
+        {
+            *nMaxDescent = 
static_cast<SwTwips>(std::ceil(stMetrics.aBounds->Bottom()));
+        }
     }
 }
 
@@ -772,16 +789,16 @@ static void GetTextArray(const OutputDevice& 
rOutputDevice, const SwDrawTextInfo
                          KernArray& rDXAry, bool bCaret = false)
 {
     GetTextArray(rOutputDevice, rInf.GetText(), rDXAry, rInf.GetIdx().get(), 
rInf.GetLen().get(),
-                 rInf.GetLayoutContext(), bCaret, rInf.GetVclCache());
+                 rInf.GetLayoutContext(), nullptr, nullptr, bCaret, 
rInf.GetVclCache());
 }
 
 static void GetTextArray(const OutputDevice& rOutputDevice, const 
SwDrawTextInfo& rInf,
-                         KernArray& rDXAry, sal_Int32 nLen, bool bCaret = 
false)
+                         KernArray& rDXAry, sal_Int32 nLen, SwTwips 
*nMaxAscent = nullptr, SwTwips *nMaxDescent = nullptr, bool bCaret = false)
 {
     // Substring is fine.
     assert(nLen <= rInf.GetLen().get());
     GetTextArray(rOutputDevice, rInf.GetText(), rDXAry, rInf.GetIdx().get(), 
nLen,
-                 rInf.GetLayoutContext(), bCaret, rInf.GetVclCache());
+                 rInf.GetLayoutContext(), nMaxAscent, nMaxDescent, bCaret, 
rInf.GetVclCache());
 }
 
 static void DrawTextArray(OutputDevice& rOutputDevice, const Point& rStartPt, 
const OUString& rStr,
@@ -1581,6 +1598,8 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
 Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
 {
     Size aTextSize;
+    SwTwips nMaxAscent = 0;
+    SwTwips nMaxDescent = 0;
     const TextFrameIndex nLn = (TextFrameIndex(COMPLETE_STRING) != 
rInf.GetLen())
         ? rInf.GetLen()
         : TextFrameIndex(rInf.GetText().getLength());
@@ -1631,7 +1650,8 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
                                 GetFontLeading( rInf.GetShell(), rInf.GetOut() 
) );
 
             KernArray aKernArray;
-            GetTextArray(*pOutDev, rInf, aKernArray, sal_Int32(nLn), bCaret);
+            GetTextArray(*pOutDev, rInf, aKernArray, sal_Int32(nLn), 
&nMaxAscent, &nMaxDescent,
+                         bCaret);
             if (pGrid->IsSnapToChars())
             {
                 sw::Justify::SnapToGrid(aKernArray, rInf.GetText(), 
sal_Int32(rInf.GetIdx()),
@@ -1674,7 +1694,7 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
             rInf.GetOut().SetFont( *m_pScrFont );
 
         GetTextArray(*m_pPrinter, rInf.GetText(), aKernArray, 
sal_Int32(rInf.GetIdx()),
-                     sal_Int32(nLn), rInf.GetLayoutContext(), bCaret);
+                     sal_Int32(nLn), rInf.GetLayoutContext(), &nMaxAscent, 
&nMaxDescent, bCaret);
     }
     else
     {
@@ -1682,9 +1702,12 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
             rInf.GetOut().SetFont( *m_pPrtFont );
         aTextSize.setHeight( rInf.GetOut().GetTextHeight() );
 
-        GetTextArray(rInf.GetOut(), rInf, aKernArray, nLn.get(), bCaret);
+        GetTextArray(rInf.GetOut(), rInf, aKernArray, nLn.get(), &nMaxAscent, 
&nMaxDescent, bCaret);
     }
 
+    rInf.SetExtraAscent(std::max(SwTwips{ 0 }, nMaxAscent));
+    rInf.SetExtraDescent(std::max(SwTwips{ 0 }, nMaxDescent));
+
     if (bCompress)
     {
         rInf.SetKanaDiff(rInf.GetScriptInfo()->Compress(aKernArray, 
rInf.GetIdx(), nLn, rInf.GetKanaComp(),
diff --git a/toolkit/source/awt/vclxfont.cxx b/toolkit/source/awt/vclxfont.cxx
index 47fad780d73b..32a42dec7579 100644
--- a/toolkit/source/awt/vclxfont.cxx
+++ b/toolkit/source/awt/vclxfont.cxx
@@ -153,7 +153,7 @@ sal_Int32 VCLXFont::getStringWidthArray( const OUString& 
str, css::uno::Sequence
         vcl::Font aOldFont = pOutDev->GetFont();
         pOutDev->SetFont( maFont );
         KernArray aDXA;
-        nRet = basegfx::fround(pOutDev->GetTextArray(str, &aDXA));
+        nRet = basegfx::fround(pOutDev->GetTextArray(str, &aDXA).nWidth);
         rDXArray.realloc(aDXA.size());
         sal_Int32* pArray = rDXArray.getArray();
         for (size_t i = 0, nLen = aDXA.size(); i < nLen; ++i)
diff --git a/vcl/qa/cppunit/complextext.cxx b/vcl/qa/cppunit/complextext.cxx
index 24958c0b0637..b7a04d98ad80 100644
--- a/vcl/qa/cppunit/complextext.cxx
+++ b/vcl/qa/cppunit/complextext.cxx
@@ -86,7 +86,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testArabic)
         3899, 4550, 5119, 5689, 5689, 6307, 6925, 8484, 9135, 9705, 10927,
         10927, 11497, 12595, 12595 };
     KernArray aCharWidths;
-    tools::Long nTextWidth = 
basegfx::fround<tools::Long>(pOutDev->GetTextArray(aOneTwoThree, &aCharWidths));
+    tools::Long nTextWidth
+        = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aOneTwoThree, 
&aCharWidths).nWidth);
 
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     // this sporadically returns 75 or 74 on some of the windows tinderboxes 
eg. tb73
@@ -267,7 +268,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
     // and the next ones are all zero width.
     nRefTextWidth = 3611;
     aRefCharWidths = { 1168, 1168, 1819, 2389, 3611, 3611 };
-    nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/false));
+    nTextWidth = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
false).nWidth);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
@@ -275,7 +277,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
     aRefCharWidths = { 584, 1168, 1819, 2389, 3000, 3611 };
-    nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/true));
+    nTextWidth = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
@@ -284,7 +287,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
     // component count.
     aText = u"لَاَ بلَاَ"_ustr;
     aRefCharWidths = { 584, 584, 1168, 1168, 1819, 2389, 3000, 3000, 3611, 
3611 };
-    nTextWidth2 = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/true));
+    nTextWidth2 = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[0], aCharWidths[1]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[2], aCharWidths[3]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[6], aCharWidths[7]);
@@ -301,7 +305,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
     // and the next ones are all zero width.
     nRefTextWidth = 8493;
     aRefCharWidths = { 1290, 1290, 1941, 3231, 3231, 3882, 5862, 5862, 5862, 
6513, 8493, 8493, 8493 };
-    nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/false));
+    nTextWidth = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
false).nWidth);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
@@ -309,7 +314,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
     aRefCharWidths = { 645, 1290, 1941, 2586, 3231, 3882, 4542, 5202, 5862, 
6513, 7173, 7833, 8493 };
-    nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/true));
+    nTextWidth = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
@@ -340,7 +346,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
     // and the next ones are all zero width.
     nRefTextWidth = 1710;
     aRefCharWidths= { 582, 582, 842, 1111, 1710, 1710 };
-    nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/false));
+    nTextWidth = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
false).nWidth);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
@@ -348,7 +355,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
     aRefCharWidths = { 291, 582, 842, 1111, 1410, 1710 };
-    nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/true));
+    nTextWidth = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
@@ -357,7 +365,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
     // component count.
     aText = u"لَاَ بلَاَ"_ustr;
     aRefCharWidths = { 291, 291, 582, 582, 842, 1111, 1410, 1410, 1710, 1710 };
-    nTextWidth2 = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/true));
+    nTextWidth2 = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[0], aCharWidths[1]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[2], aCharWidths[3]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[6], aCharWidths[7]);
@@ -379,7 +388,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
     nRefTextWidth = 5996;
     aRefCharWidths = { 519, 519, 811, 1606, 1606, 1606, 1898, 2439, 2439, 2731,
                        3544, 3544, 3544, 3836, 4634, 4634, 4926, 5996, 5996, 
5996 };
-    nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/false));
+    nTextWidth = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
false).nWidth);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
@@ -388,7 +398,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
     // components.
     aRefCharWidths = { 269, 519, 811, 1080, 1348, 1606, 1898, 2171, 2439, 2731,
                        3004, 3278, 3544, 3836, 4138, 4634, 4926, 5199, 5494, 
5996 };
-    nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths, 0, -1, /*bCaret*/true));
+    nTextWidth = basegfx::fround<tools::Long>(
+        pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
@@ -410,7 +421,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testTdf152048)
     tools::Long nRefTextWidth(5495);
 
     KernArray aCharWidths;
-    tools::Long nTextWidth = 
basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, &aCharWidths));
+    tools::Long nTextWidth
+        = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths).nWidth);
 
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
@@ -443,7 +455,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testTdf152048_2)
 
     // get an compare the default text array
     KernArray aCharWidths;
-    auto nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(u"ع a 
ع"_ustr, &aCharWidths));
+    auto nTextWidth
+        = basegfx::fround<tools::Long>(pOutDev->GetTextArray(u"ع a ع"_ustr, 
&aCharWidths).nWidth);
 
     // Text width should always be equal to the width of the last glyph in the
     // kern array.
@@ -514,7 +527,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, 
testMixedCJKLatinScript_glyph_advanceme
     tools::Long nRefTextWidth = 704;
     std::vector<sal_Int32> aRefCharWidths = { 72, 144, 190, 236, 259, 305, 
333, 379, 425, 474, 523, 551, 567, 612, 658, 704 };
     KernArray aCharWidths;
-    tools::Long nTextWidth = 
basegfx::fround<tools::Long>(pOutDev->GetTextArray(aTestScript, &aCharWidths));
+    tools::Long nTextWidth
+        = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aTestScript, 
&aCharWidths).nWidth);
 
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
@@ -621,7 +635,7 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, 
testPartialKoreanJamoComposition)
 
     // Absolute character widths for the complete array.
     KernArray aCompleteWidths;
-    auto nCompleteWidth = pOutDev->GetTextArray(aStr, &aCompleteWidths);
+    auto nCompleteWidth = pOutDev->GetTextArray(aStr, &aCompleteWidths).nWidth;
 
     CPPUNIT_ASSERT_EQUAL(size_t{ 3 }, aCompleteWidths.size());
 
@@ -632,8 +646,11 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, 
testPartialKoreanJamoComposition)
     for (sal_Int32 i = 0; i < 3; ++i)
     {
         KernArray aFragmentWidths;
-        auto nFragmentWidth = pOutDev->GetPartialTextArray(
-            aStr, &aFragmentWidths, /*nIndex*/ 0, /*nLen*/ 3, /*nPartIndex*/ 
i, /*nPartLen*/ 1);
+        auto nFragmentWidth
+            = pOutDev
+                  ->GetPartialTextArray(aStr, &aFragmentWidths, /*nIndex*/ 0, 
/*nLen*/ 3,
+                                        /*nPartIndex*/ i, /*nPartLen*/ 1)
+                  .nWidth;
         nPartialWidth += nFragmentWidth;
 
         CPPUNIT_ASSERT_EQUAL(size_t{ 1 }, aFragmentWidths.size());
@@ -654,7 +671,7 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, 
testPartialArabicComposition)
 
     // Absolute character widths for the complete array.
     KernArray aCompleteWidths;
-    auto nCompleteWidth = pOutDev->GetTextArray(aStr, &aCompleteWidths);
+    auto nCompleteWidth = pOutDev->GetTextArray(aStr, &aCompleteWidths).nWidth;
 
     CPPUNIT_ASSERT_EQUAL(size_t{ 7 }, aCompleteWidths.size());
 
@@ -665,8 +682,11 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, 
testPartialArabicComposition)
     for (sal_Int32 i = 0; i < 7; ++i)
     {
         KernArray aFragmentWidths;
-        auto nFragmentWidth = pOutDev->GetPartialTextArray(
-            aStr, &aFragmentWidths, /*nIndex*/ 0, /*nLen*/ 7, /*nPartIndex*/ 
i, /*nPartLen*/ 1);
+        auto nFragmentWidth
+            = pOutDev
+                  ->GetPartialTextArray(aStr, &aFragmentWidths, /*nIndex*/ 0, 
/*nLen*/ 7,
+                                        /*nPartIndex*/ i, /*nPartLen*/ 1)
+                  .nWidth;
         nPartialWidth += nFragmentWidth;
 
         CPPUNIT_ASSERT_EQUAL(size_t{ 1 }, aFragmentWidths.size());
diff --git a/vcl/qa/cppunit/text.cxx b/vcl/qa/cppunit/text.cxx
index b8847f5c6247..3cf88138eb29 100644
--- a/vcl/qa/cppunit/text.cxx
+++ b/vcl/qa/cppunit/text.cxx
@@ -242,7 +242,8 @@ CPPUNIT_TEST_FIXTURE(VclTextTest, 
testSimpleTextFontSpecificKerning)
     tools::Long nRefTextWidth = 2671;
     std::vector<sal_Int32> aRefCharWidths = { 1270, 2671 };
     KernArray aCharWidths;
-    tools::Long nTextWidth = 
basegfx::fround<tools::Long>(pOutDev->GetTextArray(aAV, &aCharWidths));
+    tools::Long nTextWidth
+        = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aAV, 
&aCharWidths).nWidth);
 
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths[0], 
aCharWidths.get_subunit_array()[0]);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths[1], 
aCharWidths.get_subunit_array()[1]);
@@ -291,7 +292,8 @@ CPPUNIT_TEST_FIXTURE(VclTextTest, testSimpleTextNoKerning)
     tools::Long nRefTextWidth = 2802;
     std::vector<sal_Int32> aRefCharWidths = { 1401, 2802 };
     KernArray aCharWidths;
-    tools::Long nTextWidth = 
basegfx::fround<tools::Long>(pOutDev->GetTextArray(aAV, &aCharWidths));
+    tools::Long nTextWidth
+        = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aAV, 
&aCharWidths).nWidth);
 
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths[0], 
aCharWidths.get_subunit_array()[0]);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths[1], 
aCharWidths.get_subunit_array()[1]);
@@ -1029,7 +1031,7 @@ CPPUNIT_TEST_FIXTURE(VclTextTest, 
testPartialTextArraySizeMatch)
 
     // Absolute character widths for the complete array.
     KernArray aCompleteWidths;
-    auto nCompleteWidth = pOutDev->GetTextArray(aWater, &aCompleteWidths);
+    auto nCompleteWidth = pOutDev->GetTextArray(aWater, 
&aCompleteWidths).nWidth;
 
     CPPUNIT_ASSERT_EQUAL(size_t{ 5 }, aCompleteWidths.size());
 
@@ -1040,8 +1042,11 @@ CPPUNIT_TEST_FIXTURE(VclTextTest, 
testPartialTextArraySizeMatch)
     for (sal_Int32 i = 0; i < 5; ++i)
     {
         KernArray aFragmentWidths;
-        auto nFragmentWidth = pOutDev->GetPartialTextArray(
-            aWater, &aFragmentWidths, /*nIndex*/ 0, /*nLen*/ 5, /*nPartIndex*/ 
i, /*nPartLen*/ 1);
+        auto nFragmentWidth
+            = pOutDev
+                  ->GetPartialTextArray(aWater, &aFragmentWidths, /*nIndex*/ 
0, /*nLen*/ 5,
+                                        /*nPartIndex*/ i, /*nPartLen*/ 1)
+                  .nWidth;
         nPartialWidth += nFragmentWidth;
 
         CPPUNIT_ASSERT_EQUAL(size_t{ 1 }, aFragmentWidths.size());
diff --git a/vcl/source/filter/wmf/emfwr.cxx b/vcl/source/filter/wmf/emfwr.cxx
index 3b349b9f70ac..92a2320369c1 100644
--- a/vcl/source/filter/wmf/emfwr.cxx
+++ b/vcl/source/filter/wmf/emfwr.cxx
@@ -882,7 +882,7 @@ void EMFWriter::ImplWriteTextRecord( const Point& rPos, 
const OUString& rText, K
     }
     else
     {
-        nNormWidth = basegfx::fround<sal_uInt32>(maVDev->GetTextArray(rText, 
&aOwnArray));
+        nNormWidth = basegfx::fround<sal_uInt32>(maVDev->GetTextArray(rText, 
&aOwnArray).nWidth);
         pDX = aOwnArray;
     }
 
diff --git a/vcl/source/filter/wmf/wmfwr.cxx b/vcl/source/filter/wmf/wmfwr.cxx
index 3f975ec5e659..70b00a895720 100644
--- a/vcl/source/filter/wmf/wmfwr.cxx
+++ b/vcl/source/filter/wmf/wmfwr.cxx
@@ -1198,7 +1198,8 @@ void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
                 pVirDev->SetFont( aSrcFont );
                 const sal_Int32 nLen = aTemp.getLength();
                 KernArray aDXAry;
-                const sal_Int32 nNormSize = 
basegfx::fround(pVirDev->GetTextArray( aTemp, nLen ? &aDXAry : nullptr ));
+                const sal_Int32 nNormSize = basegfx::fround(
+                    pVirDev->GetTextArray(aTemp, nLen ? &aDXAry : 
nullptr).nWidth);
                 if (nLen && nNormSize == 0)
                 {
                     OSL_FAIL("Impossible div by 0 action: 
MetaStretchTextAction!");
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 5c5edd3b0612..d0bdd7ccf68f 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -650,7 +650,7 @@ double OutputDevice::GetTextWidthDouble(const OUString& 
rStr, sal_Int32 nIndex,
                                         vcl::text::TextLayoutCache const* 
const pLayoutCache,
                                         SalLayoutGlyphs const* const 
pSalLayoutCache) const
 {
-    return GetTextArray(rStr, nullptr, nIndex, nLen, false, pLayoutCache, 
pSalLayoutCache);
+    return GetTextArray(rStr, nullptr, nIndex, nLen, false, pLayoutCache, 
pSalLayoutCache).nWidth;
 }
 
 tools::Long OutputDevice::GetTextHeight() const
@@ -781,27 +781,26 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, 
const OUString& rStr,
         mpAlphaVDev->DrawTextArray( rStartPt, rStr, pDXAry, pKashidaAry, 
nIndex, nLen, flags );
 }
 
-double OutputDevice::GetTextArray( const OUString& rStr, KernArray* pKernArray,
-                                 sal_Int32 nIndex, sal_Int32 nLen, bool bCaret,
-                                 vcl::text::TextLayoutCache const*const 
pLayoutCache,
-                                 SalLayoutGlyphs const*const pSalLayoutCache) 
const
+vcl::TextArrayMetrics
+OutputDevice::GetTextArray(const OUString& rStr, KernArray* pKernArray, 
sal_Int32 nIndex,
+                           sal_Int32 nLen, bool bCaret,
+                           vcl::text::TextLayoutCache const* const 
pLayoutCache,
+                           SalLayoutGlyphs const* const pSalLayoutCache) const
 {
     return GetPartialTextArray(rStr, pKernArray, nIndex, nLen, nIndex, nLen, 
bCaret, pLayoutCache,
                                pSalLayoutCache);
 }
 
-double OutputDevice::GetPartialTextArray(const OUString &rStr,
-                                         KernArray* pKernArray,
-                                         sal_Int32 nIndex,
-                                         sal_Int32 nLen,
-                                         sal_Int32 nPartIndex,
-                                         sal_Int32 nPartLen,
-                                         bool bCaret,
-                                         const vcl::text::TextLayoutCache* 
pLayoutCache,
-                                         const SalLayoutGlyphs* 
pSalLayoutCache) const
+vcl::TextArrayMetrics
+OutputDevice::GetPartialTextArray(const OUString& rStr, KernArray* pKernArray, 
sal_Int32 nIndex,
+                                  sal_Int32 nLen, sal_Int32 nPartIndex, 
sal_Int32 nPartLen,
+                                  bool bCaret, const 
vcl::text::TextLayoutCache* pLayoutCache,
+                                  const SalLayoutGlyphs* pSalLayoutCache) const
 {
-    if( nIndex >= rStr.getLength() )
-        return 0; // TODO: this looks like a buggy caller?
+    if (nIndex >= rStr.getLength())
+    {
+        return {}; // TODO: this looks like a buggy caller?
+    }
 
     if( nLen < 0 || nIndex + nLen >= rStr.getLength() )
     {
@@ -844,7 +843,8 @@ double OutputDevice::GetPartialTextArray(const OUString 
&rStr,
             pDXAry->resize(nPartLen);
             std::fill(pDXAry->begin(), pDXAry->end(), 0);
         }
-        return 0;
+
+        return {};
     }
 
     std::unique_ptr<std::vector<double>> xDXPixelArray;
@@ -902,7 +902,18 @@ double OutputDevice::GetPartialTextArray(const OUString 
&rStr,
             (*pDXAry)[i] = basegfx::fround((*pDXPixelArray)[i]);
     }
 
-    return ImplDevicePixelToLogicWidthDouble(nWidth);
+    vcl::TextArrayMetrics stReturnValue;
+
+    basegfx::B2DRectangle stRect;
+    if (pSalLayout->GetBoundRect(stRect))
+    {
+        auto stRect2 = SalLayout::BoundRect2Rectangle(stRect);
+        stReturnValue.aBounds = ImplDevicePixelToLogic(stRect2);
+    }
+
+    stReturnValue.nWidth = ImplDevicePixelToLogicWidthDouble(nWidth);
+
+    return stReturnValue;
 }
 
 void OutputDevice::GetCaretPositions( const OUString& rStr, KernArray& 
rCaretXArray,
diff --git a/vcl/source/text/textlayout.cxx b/vcl/source/text/textlayout.cxx
index d43549a589d3..5621a9d4c1f6 100644
--- a/vcl/source/text/textlayout.cxx
+++ b/vcl/source/text/textlayout.cxx
@@ -486,7 +486,8 @@ namespace vcl
     tools::Long DefaultTextLayout::GetTextArray( const OUString& _rText, 
KernArray* _pDXArray,
         sal_Int32 _nStartIndex, sal_Int32 _nLength, bool bCaret ) const
     {
-        return basegfx::fround<tools::Long>(m_rTargetDevice.GetTextArray( 
_rText, _pDXArray, _nStartIndex, _nLength, bCaret ));
+        return basegfx::fround<tools::Long>(
+            m_rTargetDevice.GetTextArray(_rText, _pDXArray, _nStartIndex, 
_nLength, bCaret).nWidth);
     }
 
     sal_Int32 DefaultTextLayout::GetTextBreak( const OUString& _rText, 
tools::Long _nMaxTextWidth, sal_Int32 _nStartIndex, sal_Int32 _nLength ) const
@@ -594,7 +595,9 @@ namespace vcl
             return 0;
 
         // retrieve the character widths from the reference device
-        tools::Long nTextWidth = 
basegfx::fround<tools::Long>(m_rReferenceDevice.GetTextArray( _rText, _pDXAry, 
_nStartIndex, _nLength, bCaret ));
+        tools::Long nTextWidth = basegfx::fround<tools::Long>(
+            m_rReferenceDevice.GetTextArray(_rText, _pDXAry, _nStartIndex, 
_nLength, bCaret)
+                .nWidth);
 #if OSL_DEBUG_LEVEL > 1
         if ( _pDXAry )
         {

Reply via email to