[Libreoffice-commits] core.git: vcl/source

Martin Hosken (via logerrit) logerrit at kemper.freedesktop.org
Mon Aug 5 02:27:52 UTC 2019


 vcl/source/gdi/CommonSalLayout.cxx |  112 ++++++++++++++++++++-----------------
 1 file changed, 61 insertions(+), 51 deletions(-)

New commits:
commit 21a54877f7e819491d7984a3c318100fa2eddfae
Author:     Martin Hosken <martin_hosken at sil.org>
AuthorDate: Wed Jul 24 10:25:44 2019 +0700
Commit:     Martin Hosken <martin_hosken at sil.org>
CommitDate: Mon Aug 5 04:27:16 2019 +0200

    Graphite fonts don't need runs broken by script
    
    This allows Graphite fonts to work with unencoded characters (or those
    just added to Unicode). It also allows cross script shaping if desired.
    
    Change-Id: I26334b63a2a8715c0507dbe5ec315aebf5f2f415
    Reviewed-on: https://gerrit.libreoffice.org/76213
    Tested-by: Jenkins
    Reviewed-by: Khaled Hosny <khaledhosny at eglug.org>

diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 7d67014031cc..b77eca31a389 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -21,6 +21,7 @@
 
 #include <hb-icu.h>
 #include <hb-ot.h>
+#include <hb-graphite2.h>
 
 #include <sallayout.hxx>
 
@@ -290,6 +291,7 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs*
     }
 
     hb_font_t *pHbFont = GetFont().GetHbFont();
+    bool isGraphite = hb_graphite2_face_get_gr_face(hb_font_get_face(pHbFont)) != nullptr;
 
     int nGlyphCapacity = 2 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos);
     m_GlyphItems.Impl()->reserve(nGlyphCapacity);
@@ -338,8 +340,8 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs*
             break;
 
         // Find script subruns.
-        int nCurrentPos = nBidiMinRunPos;
         std::vector<SubRun> aSubRuns;
+        int nCurrentPos = nBidiMinRunPos;
         size_t k = 0;
         for (; k < pTextLayout->runs.size(); ++k)
         {
@@ -350,67 +352,75 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs*
             }
         }
 
-        while (nCurrentPos < nBidiEndRunPos && k < pTextLayout->runs.size())
+        if (isGraphite)
         {
-            int32_t nMinRunPos = nCurrentPos;
-            int32_t nEndRunPos = std::min(pTextLayout->runs[k].nEnd, nBidiEndRunPos);
-            hb_direction_t aDirection = bRightToLeft ? HB_DIRECTION_RTL : HB_DIRECTION_LTR;
             hb_script_t aScript = hb_icu_script_to_script(pTextLayout->runs[k].nCode);
-            // For vertical text, further divide the runs based on character
-            // orientation.
-            if (rArgs.mnFlags & SalLayoutFlags::Vertical)
+            aSubRuns.push_back({ nBidiMinRunPos, nBidiEndRunPos, aScript, bRightToLeft ? HB_DIRECTION_RTL : HB_DIRECTION_LTR });
+        }
+        else
+        {
+            while (nCurrentPos < nBidiEndRunPos && k < pTextLayout->runs.size())
             {
-                sal_Int32 nIdx = nMinRunPos;
-                while (nIdx < nEndRunPos)
+                int32_t nMinRunPos = nCurrentPos;
+                int32_t nEndRunPos = std::min(pTextLayout->runs[k].nEnd, nBidiEndRunPos);
+                hb_direction_t aDirection = bRightToLeft ? HB_DIRECTION_RTL : HB_DIRECTION_LTR;
+                hb_script_t aScript = hb_icu_script_to_script(pTextLayout->runs[k].nCode);
+                // For vertical text, further divide the runs based on character
+                // orientation.
+                if (rArgs.mnFlags & SalLayoutFlags::Vertical)
                 {
-                    sal_Int32 nPrevIdx = nIdx;
-                    sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&nIdx);
-                    VerticalOrientation aVo = GetVerticalOrientation(aChar, rArgs.maLanguageTag);
-
-                    sal_UCS4 aVariationSelector = 0;
-                    if (nIdx < nEndRunPos)
+                    sal_Int32 nIdx = nMinRunPos;
+                    while (nIdx < nEndRunPos)
                     {
-                        sal_Int32 nNextIdx = nIdx;
-                        sal_UCS4 aNextChar = rArgs.mrStr.iterateCodePoints(&nNextIdx);
-                        if (u_hasBinaryProperty(aNextChar, UCHAR_VARIATION_SELECTOR))
+                        sal_Int32 nPrevIdx = nIdx;
+                        sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&nIdx);
+                        VerticalOrientation aVo = GetVerticalOrientation(aChar, rArgs.maLanguageTag);
+
+                        sal_UCS4 aVariationSelector = 0;
+                        if (nIdx < nEndRunPos)
                         {
-                            nIdx = nNextIdx;
-                            aVariationSelector = aNextChar;
+                            sal_Int32 nNextIdx = nIdx;
+                            sal_UCS4 aNextChar = rArgs.mrStr.iterateCodePoints(&nNextIdx);
+                            if (u_hasBinaryProperty(aNextChar, UCHAR_VARIATION_SELECTOR))
+                            {
+                                nIdx = nNextIdx;
+                                aVariationSelector = aNextChar;
+                            }
                         }
-                    }
 
-                    // Charters with U and Tu vertical orientation should
-                    // be shaped in vertical direction. But characters
-                    // with Tr should be shaped in vertical direction
-                    // only if they have vertical alternates, otherwise
-                    // they should be shaped in horizontal direction
-                    // and then rotated.
-                    // See http://unicode.org/reports/tr50/#vo
-                    if (aVo == VerticalOrientation::Upright ||
-                        aVo == VerticalOrientation::TransformedUpright ||
-                        (aVo == VerticalOrientation::TransformedRotated &&
-                         HasVerticalAlternate(aChar, aVariationSelector)))
-                    {
-                        aDirection = HB_DIRECTION_TTB;
-                    }
-                    else
-                    {
-                        aDirection = bRightToLeft ? HB_DIRECTION_RTL : HB_DIRECTION_LTR;
-                    }
+                        // Charters with U and Tu vertical orientation should
+                        // be shaped in vertical direction. But characters
+                        // with Tr should be shaped in vertical direction
+                        // only if they have vertical alternates, otherwise
+                        // they should be shaped in horizontal direction
+                        // and then rotated.
+                        // See http://unicode.org/reports/tr50/#vo
+                        if (aVo == VerticalOrientation::Upright ||
+                            aVo == VerticalOrientation::TransformedUpright ||
+                            (aVo == VerticalOrientation::TransformedRotated &&
+                             HasVerticalAlternate(aChar, aVariationSelector)))
+                        {
+                            aDirection = HB_DIRECTION_TTB;
+                        }
+                        else
+                        {
+                            aDirection = bRightToLeft ? HB_DIRECTION_RTL : HB_DIRECTION_LTR;
+                        }
 
-                    if (aSubRuns.empty() || aSubRuns.back().maDirection != aDirection)
-                        aSubRuns.push_back({ nPrevIdx, nIdx, aScript, aDirection });
-                    else
-                        aSubRuns.back().mnEnd = nIdx;
+                        if (aSubRuns.empty() || aSubRuns.back().maDirection != aDirection)
+                            aSubRuns.push_back({ nPrevIdx, nIdx, aScript, aDirection });
+                        else
+                            aSubRuns.back().mnEnd = nIdx;
+                    }
+                }
+                else
+                {
+                    aSubRuns.push_back({ nMinRunPos, nEndRunPos, aScript, aDirection });
                 }
-            }
-            else
-            {
-                aSubRuns.push_back({ nMinRunPos, nEndRunPos, aScript, aDirection });
-            }
 
-            nCurrentPos = nEndRunPos;
-            ++k;
+                nCurrentPos = nEndRunPos;
+                ++k;
+            }
         }
 
         // RTL subruns should be reversed to ensure that final glyph order is


More information about the Libreoffice-commits mailing list