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

Akash Jain akash96j at gmail.com
Wed May 11 01:09:29 UTC 2016


 vcl/unx/generic/glyphs/gcach_layout.cxx |   58 ++++++++++++++++++++++----------
 1 file changed, 41 insertions(+), 17 deletions(-)

New commits:
commit 1da9b4c24e806ad2447b4a656e2a7192755bb6a8
Author: Akash Jain <akash96j at gmail.com>
Date:   Tue May 10 17:23:13 2016 +0530

    Change code related to setting diacritic and cluster property of a character
    
    To determine whether a character is a diacritic check the characters unicode
    combining class if the font has no GDEF table.
    Also change the way to determine whether a character is in a cluster or not.
    
    Change-Id: I1ef45d5ffe610216d492ce4a1caacf2c01bfde78
    Reviewed-on: https://gerrit.libreoffice.org/24844
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Khaled Hosny <khaledhosny at eglug.org>

diff --git a/vcl/unx/generic/glyphs/gcach_layout.cxx b/vcl/unx/generic/glyphs/gcach_layout.cxx
index 8394678..81db0ae 100644
--- a/vcl/unx/generic/glyphs/gcach_layout.cxx
+++ b/vcl/unx/generic/glyphs/gcach_layout.cxx
@@ -21,6 +21,7 @@
 #include <sallayout.hxx>
 #include <salgdi.hxx>
 #include <scrptrun.h>
+#include <limits>
 
 #include <i18nlangtag/mslangid.hxx>
 
@@ -308,14 +309,16 @@ static unsigned int unicodeDecomposeCompatibility(hb_unicode_funcs_t* /*ufuncs*/
 {
     return 0;
 }
+#endif
 
 static hb_unicode_funcs_t* getUnicodeFuncs()
 {
     static hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_create(hb_icu_get_unicode_funcs());
+#if !HB_VERSION_ATLEAST(1, 1, 0)
     hb_unicode_funcs_set_decompose_compatibility_func(ufuncs, unicodeDecomposeCompatibility, nullptr, nullptr);
+#endif
     return ufuncs;
 }
-#endif
 
 class HbLayoutEngine : public ServerFontLayoutEngine
 {
@@ -489,8 +492,8 @@ bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
                 nHbFlags |= HB_BUFFER_FLAG_EOT; /* End-of-text */
 
             hb_buffer_t *pHbBuffer = hb_buffer_create();
-#if !HB_VERSION_ATLEAST(1, 1, 0)
             static hb_unicode_funcs_t* pHbUnicodeFuncs = getUnicodeFuncs();
+#if !HB_VERSION_ATLEAST(1, 1, 0)
             hb_buffer_set_unicode_funcs(pHbBuffer, pHbUnicodeFuncs);
 #endif
             hb_buffer_set_direction(pHbBuffer, bRightToLeft ? HB_DIRECTION_RTL: HB_DIRECTION_LTR);
@@ -500,12 +503,20 @@ bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
             hb_buffer_add_utf16(
                 pHbBuffer, reinterpret_cast<uint16_t const *>(pStr), nLength,
                 nMinRunPos, nRunLen);
+#if HB_VERSION_ATLEAST(0, 9, 42)
+            hb_buffer_set_cluster_level(pHbBuffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
+#endif
             hb_shape(pHbFont, pHbBuffer, nullptr, 0);
 
             int nRunGlyphCount = hb_buffer_get_length(pHbBuffer);
             hb_glyph_info_t *pHbGlyphInfos = hb_buffer_get_glyph_infos(pHbBuffer, nullptr);
             hb_glyph_position_t *pHbPositions = hb_buffer_get_glyph_positions(pHbBuffer, nullptr);
 
+            sal_Int32 nGraphemeStartPos = std::numeric_limits<sal_Int32>::max();
+            sal_Int32 nGraphemeEndPos = std::numeric_limits<sal_Int32>::min();
+            css::uno::Reference<css::i18n::XBreakIterator> xBreak = vcl::unohelper::CreateBreakIterator();
+            com::sun::star::lang::Locale aLocale(rArgs.maLanguageTag.getLocale());
+
             for (int i = 0; i < nRunGlyphCount; ++i) {
                 int32_t nGlyphIndex = pHbGlyphInfos[i].codepoint;
                 int32_t nCharPos = pHbGlyphInfos[i].cluster;
@@ -521,15 +532,26 @@ bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
                 // apply vertical flags and glyph substitution
                 // XXX: Use HB_DIRECTION_TTB above and apply whatever flags magic
                 // FixupGlyphIndex() is doing, minus the GSUB part.
-                if (nCharPos >= 0)
-                {
-                    sal_UCS4 aChar = rArgs.mrStr[nCharPos];
-                    nGlyphIndex = rFont.FixupGlyphIndex(nGlyphIndex, aChar);
-                }
+                sal_UCS4 aChar = rArgs.mrStr[nCharPos];
+                nGlyphIndex = rFont.FixupGlyphIndex(nGlyphIndex, aChar);
 
                 bool bInCluster = false;
-                if (i > 0 && pHbGlyphInfos[i].cluster == pHbGlyphInfos[i - 1].cluster)
+                if(bRightToLeft && (nCharPos < nGraphemeStartPos))
+                {
+                    sal_Int32 nDone;
+                    nGraphemeStartPos = xBreak->previousCharacters(rArgs.mrStr, nCharPos+1, aLocale,
+                                                  com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
+                }
+                else if(!bRightToLeft && (nCharPos >= nGraphemeEndPos))
+                {
+                    sal_Int32 nDone;
+                    nGraphemeEndPos = xBreak->nextCharacters(rArgs.mrStr, nCharPos, aLocale,
+                                                  com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
+                }
+                else
+                {
                     bInCluster = true;
+                }
 
                 long nGlyphFlags = 0;
                 if (bRightToLeft)
@@ -550,15 +572,12 @@ bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
                 //   but usually harmless), so we try to sniff what HarfBuzz thinks
                 //   about this glyph by checking if it gives it a zero advance
                 //   width.
-                // * If the font has no GDEF table, we just check if the glyph has
-                //   zero advance width, but this is stupid and can be wrong. A
-                //   better way would to check the character's Unicode combining
-                //   class, but unfortunately HarfBuzz gives combining marks the
-                //   cluster value of its base character, so nCharPos will be
-                //   pointing to the wrong character (but HarfBuzz might change
-                //   this in the future).
-                //   Newer versions of HarfBuzz can control this behaviour with
-                //   hb_buffer_set_cluster_level().
+                // * If the font has no GDEF table, we then check the unicode class
+                //   of the glyph. If it is a non spacing mark then the glyph is a
+                //   diacritic. This is only done if the HarfBuzz version is >= 0.9.42
+                //   Else, we fallback to setting bDiacritic to true if the x advance
+                //   of the glyph is zero. This maybe wrong in some cases but needs to
+                //   be kept until the base version of HarfBuzz can be updated.
                 bool bDiacritic = false;
                 if (hb_ot_layout_has_glyph_classes(mpHbFace))
                 {
@@ -569,9 +588,14 @@ bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
                 }
                 else
                 {
+#if HB_VERSION_ATLEAST(0, 9, 42)
+                    if(hb_unicode_general_category (pHbUnicodeFuncs, aChar) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+                        bDiacritic = true;
+#else
                     // the font lacks GDEF table
                     if (pHbPositions[i].x_advance == 0)
                         bDiacritic = true;
+#endif
                 }
 
                 if (bDiacritic)


More information about the Libreoffice-commits mailing list