[Libreoffice-commits] core.git: 2 commits - vcl/win

Khaled Hosny khaledhosny at eglug.org
Tue Nov 1 21:46:57 UTC 2016


 vcl/win/gdi/salfont.cxx |  181 +++---------------------------------------------
 1 file changed, 15 insertions(+), 166 deletions(-)

New commits:
commit 03bff1b6b953e4b7a54d2fb7bbf366bea7e959d9
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Tue Nov 1 23:15:44 2016 +0200

    tdf#71603: Improve font fallback on Windows a bit
    
    Check all missing characters, not just the first one. Also the calling
    sites for GlyphFallbackFontSubstitution hook expect the OUString to be
    updated to have only any characters not supported by the returned font.
    
    Change-Id: Ife56d692c05433f2f7fe02db3ef1562181dc3d53

diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index c8c9893..8d6f065 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -151,7 +151,7 @@ public:
     bool FindFontSubstitute( FontSelectPattern&, OUString& rMissingChars ) const override;
 private:
     HDC mhDC;
-    bool HasMissingChars( PhysicalFontFace*, const OUString& rMissingChars ) const;
+    bool HasMissingChars(PhysicalFontFace*, OUString& rMissingChars) const;
 };
 
 inline WinGlyphFallbackSubstititution::WinGlyphFallbackSubstititution( HDC hDC )
@@ -159,7 +159,7 @@ inline WinGlyphFallbackSubstititution::WinGlyphFallbackSubstititution( HDC hDC )
 {}
 
 // does a font face hold the given missing characters?
-bool WinGlyphFallbackSubstititution::HasMissingChars( PhysicalFontFace* pFace, const OUString& rMissingChars ) const
+bool WinGlyphFallbackSubstititution::HasMissingChars(PhysicalFontFace* pFace, OUString& rMissingChars) const
 {
     WinFontFace* pWinFont = static_cast< WinFontFace* >(pFace);
     FontCharMapRef xFontCharMap = pWinFont->GetFontCharMap();
@@ -194,19 +194,24 @@ bool WinGlyphFallbackSubstititution::HasMissingChars( PhysicalFontFace* pFace, c
         return false;
 
     int nMatchCount = 0;
-    // static const int nMaxMatchCount = 1; // TODO: tolerate more missing characters?
+    std::vector<sal_UCS4> rRemainingCodes;
     const sal_Int32 nStrLen = rMissingChars.getLength();
-    for( sal_Int32 nStrIdx = 0; nStrIdx < nStrLen; /* ++nStrIdx unreachable code, see the 'break' below */ )
+    sal_Int32 nStrIdx = 0;
+    while (nStrIdx < nStrLen)
     {
         const sal_UCS4 uChar = rMissingChars.iterateCodePoints( &nStrIdx );
-        nMatchCount += xFontCharMap->HasChar( uChar ) ? 1 : 0;
-        break; // for now
+        if (xFontCharMap->HasChar(uChar))
+            nMatchCount++;
+        else
+            rRemainingCodes.push_back(uChar);
     }
 
     xFontCharMap = nullptr;
 
-    const bool bHasMatches = (nMatchCount > 0);
-    return bHasMatches;
+    if (nMatchCount > 0)
+        rMissingChars = OUString(rRemainingCodes.data(), rRemainingCodes.size());
+
+    return nMatchCount > 0;
 }
 
 namespace
commit d66ec48fe879a26ec542661c04e5c2b8271b7d64
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Tue Nov 1 22:22:30 2016 +0200

    Use the font language instead of guessing it
    
    Similar to what we do with FontConfig.
    
    Change-Id: Id01dabe0b52e4e3aea54073d42b719a924025920

diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index b434184..c8c9893 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -134,150 +134,6 @@ RawFontData::RawFontData( HDC hDC, DWORD nTableTag )
 }
 
 // platform specific font substitution hooks for glyph fallback enhancement
-// TODO: move into i18n module (maybe merge with svx/ucsubset.*
-//       or merge with i18nutil/source/utility/unicode_data.h)
-struct Unicode2LangType
-{
-    sal_UCS4 mnMinCode;
-    sal_UCS4 mnMaxCode;
-    LanguageType mnLangID;
-};
-
-// entries marked with default-CJK get replaced with the default-CJK language
-#define LANGUAGE_DEFAULT_CJK 0xFFF0
-
-// map unicode ranges to languages supported by OOo
-// NOTE: due to the binary search used this list must be sorted by mnMinCode
-static Unicode2LangType aLangFromCodeChart[]= {
-    {0x0000, 0x007F, LANGUAGE_ENGLISH},             // Basic Latin
-    {0x0080, 0x024F, LANGUAGE_ENGLISH},             // Latin Extended-A and Latin Extended-B
-    {0x0250, 0x02AF, LANGUAGE_SYSTEM},              // IPA Extensions
-    {0x0370, 0x03FF, LANGUAGE_GREEK},               // Greek
-    {0x0590, 0x05FF, LANGUAGE_HEBREW},              // Hebrew
-    {0x0600, 0x06FF, LANGUAGE_ARABIC_PRIMARY_ONLY}, // Arabic
-    {0x0900, 0x097F, LANGUAGE_HINDI},               // Devanagari
-    {0x0980, 0x09FF, LANGUAGE_BENGALI},             // Bengali
-    {0x0A80, 0x0AFF, LANGUAGE_GUJARATI},            // Gujarati
-    {0x0B00, 0x0B7F, LANGUAGE_ODIA},                // Odia
-    {0x0B80, 0x0BFF, LANGUAGE_TAMIL},               // Tamil
-    {0x0C00, 0x0C7F, LANGUAGE_TELUGU},              // Telugu
-    {0x0C80, 0x0CFF, LANGUAGE_KANNADA},             // Kannada
-    {0x0D00, 0x0D7F, LANGUAGE_MALAYALAM},           // Malayalam
-    {0x0D80, 0x0D7F, LANGUAGE_SINHALESE_SRI_LANKA}, // Sinhala
-    {0x0E00, 0x0E7F, LANGUAGE_THAI},                // Thai
-    {0x0E80, 0x0EFF, LANGUAGE_LAO},                 // Lao
-    {0x0F00, 0x0FFF, LANGUAGE_TIBETAN},             // Tibetan
-    {0x1000, 0x109F, LANGUAGE_BURMESE},             // Burmese
-    {0x10A0, 0x10FF, LANGUAGE_GEORGIAN},            // Georgian
-    {0x1100, 0x11FF, LANGUAGE_KOREAN},              // Hangul Jamo, Korean-specific
-//  {0x1200, 0x139F, LANGUAGE_AMHARIC_ETHIOPIA},    // Ethiopic
-//  {0x1200, 0x139F, LANGUAGE_TIGRIGNA_ETHIOPIA},   // Ethiopic
-    {0x13A0, 0x13FF, LANGUAGE_CHEROKEE_UNITED_STATES}, // Cherokee
-//  {0x1400, 0x167F, LANGUAGE_CANADIAN_ABORIGINAL}, // Canadian Aboriginal Syllabics
-//  {0x1680, 0x169F, LANGUAGE_OGHAM},               // Ogham
-//  {0x16A0, 0x16F0, LANGUAGE_RUNIC},               // Runic
-//  {0x1700, 0x171F, LANGUAGE_TAGALOG},             // Tagalog
-//  {0x1720, 0x173F, LANGUAGE_HANUNOO},             // Hanunoo
-//  {0x1740, 0x175F, LANGUAGE_BUHID},               // Buhid
-//  {0x1760, 0x177F, LANGUAGE_TAGBANWA},            // Tagbanwa
-    {0x1780, 0x17FF, LANGUAGE_KHMER},               // Khmer
-    {0x18A0, 0x18AF, LANGUAGE_MONGOLIAN_MONGOLIAN_MONGOLIA}, // Mongolian
-//  {0x1900, 0x194F, LANGUAGE_LIMBU},               // Limbu
-//  {0x1950, 0x197F, LANGUAGE_TAILE},               // Tai Le
-//  {0x1980, 0x19DF, LANGUAGE_TAILUE},              // Tai Lue
-    {0x19E0, 0x19FF, LANGUAGE_KHMER},               // Khmer Symbols
-//  {0x1A00, 0x1A1F, LANGUAGE_BUGINESE},            // Buginese/Lontara
-//  {0x1B00, 0x1B7F, LANGUAGE_BALINESE},            // Balinese
-//  {0x1D00, 0x1DFF, LANGUAGE_NONE},                // Phonetic Symbols
-    {0x1E00, 0x1EFF, LANGUAGE_ENGLISH},             // Latin Extended Additional
-    {0x1F00, 0x1FFF, LANGUAGE_GREEK},               // Greek Extended
-    {0x2C60, 0x2C7F, LANGUAGE_ENGLISH},             // Latin Extended-C
-    {0x2E80, 0x2FFf, LANGUAGE_CHINESE_SIMPLIFIED},  // CJK Radicals Supplement + Kangxi Radical + Ideographic Description Characters
-    {0x3000, 0x303F, LANGUAGE_DEFAULT_CJK},         // CJK Symbols and punctuation
-    {0x3040, 0x30FF, LANGUAGE_JAPANESE},            // Japanese Hiragana + Katakana
-    {0x3100, 0x312F, LANGUAGE_CHINESE_TRADITIONAL}, // Bopomofo
-    {0x3130, 0x318F, LANGUAGE_KOREAN},              // Hangul Compatibility Jamo, Kocrean-specific
-    {0x3190, 0x319F, LANGUAGE_JAPANESE},            // Kanbun
-    {0x31A0, 0x31BF, LANGUAGE_CHINESE_TRADITIONAL}, // Bopomofo Extended
-    {0x31C0, 0x31EF, LANGUAGE_DEFAULT_CJK},         // CJK Ideographs
-    {0x31F0, 0x31FF, LANGUAGE_JAPANESE},            // Japanese Katakana Phonetic Extensions
-    {0x3200, 0x321F, LANGUAGE_KOREAN},              // Parenthesized Hangul
-    {0x3220, 0x325F, LANGUAGE_DEFAULT_CJK},         // Parenthesized Ideographs
-    {0x3260, 0x327F, LANGUAGE_KOREAN},              // Circled Hangul
-    {0x3280, 0x32CF, LANGUAGE_DEFAULT_CJK},         // Circled Ideographs
-    {0x32d0, 0x32FF, LANGUAGE_JAPANESE},            // Japanese Circled Katakana
-    {0x3400, 0x4DBF, LANGUAGE_DEFAULT_CJK},         // CJK Unified Ideographs Extension A
-    {0x4E00, 0x9FCF, LANGUAGE_DEFAULT_CJK},         // Unified CJK Ideographs
-    {0xA720, 0xA7FF, LANGUAGE_ENGLISH},             // Latin Extended-D
-    {0xAC00, 0xD7AF, LANGUAGE_KOREAN},              // Hangul Syllables, Korean-specific
-    {0xF900, 0xFAFF, LANGUAGE_DEFAULT_CJK},         // CJK Compatibility Ideographs
-    {0xFB00, 0xFB4F, LANGUAGE_HEBREW},              // Hebrew Presentation Forms
-    {0xFB50, 0xFDFF, LANGUAGE_ARABIC_PRIMARY_ONLY}, // Arabic Presentation Forms-A
-    {0xFE70, 0xFEFE, LANGUAGE_ARABIC_PRIMARY_ONLY}, // Arabic Presentation Forms-B
-    {0xFF65, 0xFF9F, LANGUAGE_JAPANESE},            // Japanese Halfwidth Katakana variant
-    {0xFFA0, 0xFFDC, LANGUAGE_KOREAN},              // Kocrean halfwidth hangual variant
-    {0x10140, 0x1018F, LANGUAGE_GREEK},             // Ancient Greak numbers
-    {0x1D200, 0x1D24F, LANGUAGE_GREEK},             // Ancient Greek Musical
-    {0x20000, 0x2A6DF, LANGUAGE_DEFAULT_CJK},       // CJK Unified Ideographs Extension B
-    {0x2F800, 0x2FA1F, LANGUAGE_DEFAULT_CJK}        // CJK Compatibility Ideographs Supplement
-};
-
-// get language matching to the missing char
-LanguageType MapCharToLanguage( sal_UCS4 uChar )
-{
-    // entries marked with default-CJK get replaced with the preferred CJK language
-    static bool bFirst = true;
-    if( bFirst )
-    {
-        bFirst = false;
-
-        // use method suggested in #i97086# to determine the systems default language
-        // TODO: move into i18npool or sal/osl/w32/nlsupport.c
-        LanguageType nDefaultLang = 0;
-        HKEY hKey = nullptr;
-        LONG lResult = ::RegOpenKeyExA( HKEY_LOCAL_MACHINE,
-            "SYSTEM\\CurrentControlSet\\Control\\Nls\\Language",
-            0, KEY_QUERY_VALUE, &hKey );
-        char aKeyValBuf[16];
-        DWORD nKeyValSize = sizeof(aKeyValBuf);
-        if( ERROR_SUCCESS == lResult )
-            lResult = RegQueryValueExA( hKey, "Default", nullptr, nullptr, reinterpret_cast<LPBYTE>(aKeyValBuf), &nKeyValSize );
-        aKeyValBuf[ sizeof(aKeyValBuf)-1 ] = '\0';
-        if( ERROR_SUCCESS == lResult )
-            nDefaultLang = (LanguageType)rtl_str_toInt32( aKeyValBuf, 16 );
-
-        // TODO: use the default-CJK language selected in
-        //  Tools->Options->LangSettings->Languages when it becomes available here
-        if( !nDefaultLang )
-            nDefaultLang = Application::GetSettings().GetUILanguageTag().getLanguageType();
-
-        LanguageType nDefaultCJK = MsLangId::isCJK(nDefaultLang) ? nDefaultLang : LANGUAGE_CHINESE;
-
-        // change the marked entries to preferred language
-        static const int nCount = SAL_N_ELEMENTS(aLangFromCodeChart);
-        for( int i = 0; i < nCount; ++i )
-        {
-            if( aLangFromCodeChart[ i].mnLangID == LANGUAGE_DEFAULT_CJK )
-                aLangFromCodeChart[ i].mnLangID = nDefaultCJK;
-        }
-    }
-
-    // binary search
-    int nLow = 0;
-    int nHigh = SAL_N_ELEMENTS(aLangFromCodeChart) - 1;
-    while( nLow <= nHigh )
-    {
-        int nMiddle = (nHigh + nLow) / 2;
-        if( uChar < aLangFromCodeChart[ nMiddle].mnMinCode )
-            nHigh = nMiddle - 1;
-        else if( uChar > aLangFromCodeChart[ nMiddle].mnMaxCode )
-            nLow = nMiddle + 1;
-        else
-            return aLangFromCodeChart[ nMiddle].mnLangID;
-    }
-
-    return LANGUAGE_DONTKNOW;
-}
 
 class WinPreMatchFontSubstititution
 :    public ImplPreMatchFontSubstitution
@@ -404,22 +260,10 @@ bool WinPreMatchFontSubstititution::FindFontSubstitute(FontSelectPattern& rFontS
 bool WinGlyphFallbackSubstititution::FindFontSubstitute( FontSelectPattern& rFontSelData, OUString& rMissingChars ) const
 {
     // guess a locale matching to the missing chars
-    LanguageType eLang = LANGUAGE_DONTKNOW;
+    LanguageType eLang = rFontSelData.meLanguage;
     LanguageTag aLanguageTag( eLang);
 
-    sal_Int32 nStrIdx = 0;
-    const sal_Int32 nStrLen = rMissingChars.getLength();
-    while( nStrIdx < nStrLen )
-    {
-        const sal_UCS4 uChar = rMissingChars.iterateCodePoints( &nStrIdx );
-        eLang = MapCharToLanguage( uChar );
-        if( eLang == LANGUAGE_DONTKNOW )
-            continue;
-        aLanguageTag.reset( eLang);
-        break;
-    }
-
-    // fall back to default UI locale if the missing characters are inconclusive
+    // fall back to default UI locale if the font language is inconclusive
     if( eLang == LANGUAGE_DONTKNOW )
         aLanguageTag = Application::GetSettings().GetUILanguageTag();
 


More information about the Libreoffice-commits mailing list