sw/source/core/txtnode/fntcache.cxx |   33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

New commits:
commit 7418fc88021a7d2cb45eb3b029466ed7a14d3338
Author:     Mark Hung <mark...@gmail.com>
AuthorDate: Sat Apr 16 15:36:09 2022 +0800
Commit:     Mark Hung <mark...@gmail.com>
CommitDate: Tue Apr 19 13:51:07 2022 +0200

    tdf#148594 correcting the number of kern spaces.
    
    A glyph item ( or a glyph cluster ) may be made up of
    more than one sal_Unicode values ( e.g. CJK ideograph extension
    B characters that need surrogate pairs, or unicode iVS that have
    a base character and a selector ).
    
    Insert the kern space only when KernArray value changes. I.e.
    character belongs to a different glyph item or cluster. Count the
    number of needed kern spaces in the same way.
    
    Change-Id: If79766bda37cf4d10ca5be2d51dfdc992eaf9cc9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133093
    Tested-by: Jenkins
    Reviewed-by: Mark Hung <mark...@gmail.com>

diff --git a/sw/source/core/txtnode/fntcache.cxx 
b/sw/source/core/txtnode/fntcache.cxx
index 65a4332b462d..3e1a6f9b2c67 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -1598,6 +1598,8 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
                         nSpaceSum += nHalfSpace;
                 }
 
+                tools::Long nOldValue = aKernArray[i-1];
+
                 cChPrev = nCh;
                 aKernArray[i-1] += nKernSum + nSpaceSum;
                 // In word line mode and for Arabic, we disabled the half 
space trick. If a portion
@@ -1606,10 +1608,22 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
                 // nSpaceAdd value again:
                 if ((bNoHalfSpace || m_pPrtFont->IsWordLineMode()) && i+1 == 
sal_Int32(nCnt) && nCh == CH_BLANK)
                     aKernArray[i-1] = aKernArray[i-1] - nSpaceAdd;
+
+                // Some glyph items use more than one sal_Unicode, eg. CJK 
ideograph extensions
+                // or unicode IVS. Don't assign space multiple times in case 
the orginal text array
+                // have the same values.
+                while(i < sal_Int32(nCnt) && aKernArray[i] == nOldValue)
+                {
+                    aKernArray[i] = aKernArray[i-1];
+                    ++i;
+                }
             }
 
             // the layout engine requires the total width of the output
-            aKernArray[sal_Int32(rInf.GetLen()) - 1] += nKernSum + nSpaceSum;
+            tools::Long nOldValue = aKernArray[sal_Int32(rInf.GetLen()) - 1];
+            for(sal_Int32 i = sal_Int32(rInf.GetLen()) - 1; i >= 0 && 
aKernArray[i] == nOldValue; --i)
+                aKernArray[i] += nKernSum + nSpaceSum;
+
 
             if( rInf.GetGreyWave() )
             {
@@ -1906,8 +1920,23 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
     if (nLn)
     {
         aTextSize.setWidth(aKernArray[sal_Int32(nLn) - 1]);
+
+        // Note that we can't simply use sal_Int(nLn) - 1 as nSpaceCount
+        // because a glyph may be made up of more than one characters.
+        sal_Int32 nSpaceCount = 0;
+        tools::Long nOldValue = aKernArray[0];
+
+        for(sal_Int32 i = 1; i < sal_Int32(nLn); ++i)
+        {
+            if (nOldValue != aKernArray[i])
+            {
+                ++nSpaceCount;
+                nOldValue = aKernArray[i];
+            }
+        }
+
         if (rInf.GetKern())
-            aTextSize.AdjustWidth((sal_Int32(nLn) - 1) * rInf.GetKern());
+            aTextSize.AdjustWidth(nSpaceCount * rInf.GetKern());
     }
 
     OSL_ENSURE( !rInf.GetShell() ||

Reply via email to