vcl/inc/ImplLayoutArgs.hxx   |    2 ++
 vcl/inc/sallayout.hxx        |   11 +++++++++--
 vcl/source/gdi/sallayout.cxx |   41 ++++++++++++++++++++++++++---------------
 3 files changed, 37 insertions(+), 17 deletions(-)

New commits:
commit df044d1558d340e51d42264f212c3247c534f6da
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Sun Jan 16 21:01:48 2022 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Mon Jan 17 10:04:35 2022 +0100

    ensure glyph fallback would use the correct dxarray variant
    
    Change-Id: I4f7183f2f038bcc780e9438b04ee4d15b945d065
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128489
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/vcl/inc/ImplLayoutArgs.hxx b/vcl/inc/ImplLayoutArgs.hxx
index fa5e8005ba00..fa94562ca86c 100644
--- a/vcl/inc/ImplLayoutArgs.hxx
+++ b/vcl/inc/ImplLayoutArgs.hxx
@@ -56,6 +56,8 @@ public:
     bool GetNextPos(int* nCharPos, bool* bRTL);
     bool GetNextRun(int* nMinRunPos, int* nEndRunPos, bool* bRTL);
     void AddFallbackRun(int nMinRunPos, int nEndRunPos, bool bRTL);
+    bool HasDXArray() const { return mpDXArray || mpAltNaturalDXArray; }
+
     // methods used by BiDi and glyph fallback
     bool HasFallbackRun() const;
     bool PrepareFallback(const SalLayoutGlyphsImpl* pGlyphsImpl);
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index f5ffd0f2e587..847c22ace091 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -82,7 +82,11 @@ public:
 
     void SetIncomplete(bool bIncomplete);
 
-public:
+    template<typename DC>
+    void            ImplAdjustMultiLayout(vcl::text::ImplLayoutArgs& rArgs,
+                                          vcl::text::ImplLayoutArgs& 
rMultiArgs,
+                                          const DC* pMultiDXArray);
+
     virtual         ~MultiSalLayout() override;
 
 private:
@@ -97,7 +101,10 @@ private:
 
 class VCL_DLLPUBLIC GenericSalLayout : public SalLayout
 {
-    friend void MultiSalLayout::AdjustLayout(vcl::text::ImplLayoutArgs&);
+    template<typename DC> friend void MultiSalLayout::ImplAdjustMultiLayout(
+            vcl::text::ImplLayoutArgs& rArgs,
+            vcl::text::ImplLayoutArgs& rMultiArgs,
+            const DC* pMultiDXArray);
 
 public:
                     GenericSalLayout(LogicalFontInstance&);
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index be020c2f11ae..abad66427491 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -648,7 +648,7 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
     vcl::text::ImplLayoutArgs aMultiArgs = rArgs;
     std::vector<DeviceCoordinate> aJustificationArray;
 
-    if( !rArgs.mpDXArray && rArgs.mnLayoutWidth )
+    if( !rArgs.HasDXArray() && rArgs.mnLayoutWidth )
     {
         // for stretched text in a MultiSalLayout the target width needs to be
         // distributed by individually adjusting its virtual character widths
@@ -713,6 +713,17 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
         }
     }
 
+    if (aMultiArgs.mpAltNaturalDXArray)
+        ImplAdjustMultiLayout(rArgs, aMultiArgs, 
aMultiArgs.mpAltNaturalDXArray);
+    else
+        ImplAdjustMultiLayout(rArgs, aMultiArgs, aMultiArgs.mpDXArray);
+}
+
+template<typename DC>
+void MultiSalLayout::ImplAdjustMultiLayout(vcl::text::ImplLayoutArgs& rArgs,
+                                           vcl::text::ImplLayoutArgs& 
rMultiArgs,
+                                           const DC* pMultiDXArray)
+{
     // Compute rtl flags, since in some scripts glyphs/char order can be
     // reversed for a few character sequences e.g. Myanmar
     std::vector<bool> vRtl(rArgs.mnEndCharPos - rArgs.mnMinCharPos, false);
@@ -739,10 +750,10 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
         // now adjust the individual components
         if( n > 0 )
         {
-            aMultiArgs.maRuns = maFallbackRuns[ n-1 ];
-            aMultiArgs.mnFlags |= SalLayoutFlags::ForFallback;
+            rMultiArgs.maRuns = maFallbackRuns[ n-1 ];
+            rMultiArgs.mnFlags |= SalLayoutFlags::ForFallback;
         }
-        mpLayouts[n]->AdjustLayout( aMultiArgs );
+        mpLayouts[n]->AdjustLayout( rMultiArgs );
 
         // remove unused parts of component
         if( n > 0 )
@@ -841,7 +852,7 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
         }
 
         // skip to end of layout run and calculate its advance width
-        DeviceCoordinate nRunAdvance = 0;
+        DC nRunAdvance = 0;
         bool bKeepNotDef = (nFBLevel >= nLevel);
         for(;;)
         {
@@ -897,7 +908,7 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
                 bKeepNotDef = bNeedFallback;
             }
             // check for reordered glyphs
-            if (aMultiArgs.mpDXArray &&
+            if (pMultiDXArray &&
                 nRunVisibleEndChar < mnEndCharPos &&
                 nRunVisibleEndChar >= mnMinCharPos &&
                 pGlyphs[n]->charPos() < mnEndCharPos &&
@@ -905,14 +916,14 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
             {
                 if (vRtl[nActiveCharPos - mnMinCharPos])
                 {
-                    if (aMultiArgs.mpDXArray[nRunVisibleEndChar-mnMinCharPos]
-                        >= aMultiArgs.mpDXArray[pGlyphs[n]->charPos() - 
mnMinCharPos])
+                    if (pMultiDXArray[nRunVisibleEndChar-mnMinCharPos]
+                        >= pMultiDXArray[pGlyphs[n]->charPos() - mnMinCharPos])
                     {
                         nRunVisibleEndChar = pGlyphs[n]->charPos();
                     }
                 }
-                else if (aMultiArgs.mpDXArray[nRunVisibleEndChar-mnMinCharPos]
-                         <= aMultiArgs.mpDXArray[pGlyphs[n]->charPos() - 
mnMinCharPos])
+                else if (pMultiDXArray[nRunVisibleEndChar-mnMinCharPos]
+                         <= pMultiDXArray[pGlyphs[n]->charPos() - 
mnMinCharPos])
                 {
                     nRunVisibleEndChar = pGlyphs[n]->charPos();
                 }
@@ -921,7 +932,7 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
 
         // if a justification array is available
         // => use it directly to calculate the corresponding run width
-        if( aMultiArgs.mpDXArray )
+        if (pMultiDXArray)
         {
             // the run advance is the width from the first char
             // in the run to the first char in the next run
@@ -930,16 +941,16 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
             if (nActiveCharIndex >= 0 && vRtl[nActiveCharIndex])
             {
               if (nRunVisibleEndChar > mnMinCharPos && nRunVisibleEndChar <= 
mnEndCharPos)
-                  nRunAdvance -= aMultiArgs.mpDXArray[nRunVisibleEndChar - 1 - 
mnMinCharPos];
+                  nRunAdvance -= pMultiDXArray[nRunVisibleEndChar - 1 - 
mnMinCharPos];
               if (nLastRunEndChar > mnMinCharPos && nLastRunEndChar <= 
mnEndCharPos)
-                  nRunAdvance += aMultiArgs.mpDXArray[nLastRunEndChar - 1 - 
mnMinCharPos];
+                  nRunAdvance += pMultiDXArray[nLastRunEndChar - 1 - 
mnMinCharPos];
             }
             else
             {
                 if (nRunVisibleEndChar >= mnMinCharPos)
-                  nRunAdvance += aMultiArgs.mpDXArray[nRunVisibleEndChar - 
mnMinCharPos];
+                  nRunAdvance += pMultiDXArray[nRunVisibleEndChar - 
mnMinCharPos];
                 if (nLastRunEndChar >= mnMinCharPos)
-                  nRunAdvance -= aMultiArgs.mpDXArray[nLastRunEndChar - 
mnMinCharPos];
+                  nRunAdvance -= pMultiDXArray[nLastRunEndChar - mnMinCharPos];
             }
             nLastRunEndChar = nRunVisibleEndChar;
             nRunVisibleEndChar = pGlyphs[nFirstValid]->charPos();

Reply via email to