Changeset 170207 in webkit


Ignore:
Timestamp:
Jun 20, 2014 2:17:39 PM (10 years ago)
Author:
mmaxfield@apple.com
Message:

[iOS] Support Khmer and Lao fallback fonts
https://bugs.webkit.org/show_bug.cgi?id=134114

Reviewed by Enrica Casucci.

Source/WebCore:
iOS has fonts which have glyphs for the Khmer and Lao languages.

This patch also does a little refactoring of the language-specific fallback
font path to increase readability.

Test: fast/text/khmer-lao-font.html

  • platform/graphics/ios/FontCacheIOS.mm:

(WebCore::languageSpecificFallbackFont):
(WebCore::FontCache::systemFallbackForCharacters):

LayoutTests:
Simply dump the render tree of a page that includes Khmer and Lao text. The success
of this test depends on font font metrics being different than system fallback font
(which just shows rectangles instead of glyphs).

  • fast/text/khmer-lao-font.html: Added.
  • platform/ios-sim/fast/text/khmer-lao-font-expected.txt: Added.
  • platform/mac/fast/text/khmer-lao-font-expected.txt: Added.
Location:
trunk
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r170203 r170207  
     12014-06-20  Myles C. Maxfield  <mmaxfield@apple.com>
     2
     3        [iOS] Support Khmer and Lao fallback fonts
     4        https://bugs.webkit.org/show_bug.cgi?id=134114
     5
     6        Reviewed by Enrica Casucci.
     7
     8        Simply dump the render tree of a page that includes Khmer and Lao text. The success
     9        of this test depends on font font metrics being different than system fallback font
     10        (which just shows rectangles instead of glyphs).
     11
     12        * fast/text/khmer-lao-font.html: Added.
     13        * platform/ios-sim/fast/text/khmer-lao-font-expected.txt: Added.
     14        * platform/mac/fast/text/khmer-lao-font-expected.txt: Added.
     15
    1162014-06-20  Simon Fraser  <simon.fraser@apple.com>
    217
  • trunk/Source/WebCore/ChangeLog

    r170205 r170207  
     12014-06-20  Myles C. Maxfield  <mmaxfield@apple.com>
     2
     3        [iOS] Support Khmer and Lao fallback fonts
     4        https://bugs.webkit.org/show_bug.cgi?id=134114
     5
     6        Reviewed by Enrica Casucci.
     7
     8        iOS has fonts which have glyphs for the Khmer and Lao languages.
     9
     10        This patch also does a little refactoring of the language-specific fallback
     11        font path to increase readability.
     12
     13        Test: fast/text/khmer-lao-font.html
     14
     15        * platform/graphics/ios/FontCacheIOS.mm:
     16        (WebCore::languageSpecificFallbackFont):
     17        (WebCore::FontCache::systemFallbackForCharacters):
     18
    1192014-06-20  Anders Carlsson  <andersca@apple.com>
    220
  • trunk/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm

    r166182 r170207  
    100100}
    101101
     102enum class LanguageSpecificFont {
     103    None,
     104    ChineseJapanese,
     105    Korean,
     106    Cyrillic,
     107    Arabic,
     108    Hebrew,
     109    Indic,
     110    Thai,
     111    Lao,
     112    Tibetan,
     113    CanadianAboriginalSyllabic,
     114    Khmer,
     115    Emoji,
     116};
     117
     118static LanguageSpecificFont languageSpecificFallbackFont(UChar32 c)
     119{
     120    static bool isGB18030ComplianceRequired = wkIsGB18030ComplianceRequired();
     121
     122    // The following ranges are Korean Hangul and should be rendered by AppleSDGothicNeo
     123    // U+1100 - U+11FF
     124    // U+3130 - U+318F
     125    // U+AC00 - U+D7A3
     126
     127    // These are Cyrillic and should be rendered by Helvetica Neue
     128    // U+0400 - U+052F
     129
     130    if (c < 0x400)
     131        return LanguageSpecificFont::None;
     132    if (c <= 0x52F)
     133        return LanguageSpecificFont::Cyrillic;
     134    if (c < 0x590)
     135        return LanguageSpecificFont::None;
     136    if (c < 0x600)
     137        return LanguageSpecificFont::Hebrew;
     138    if (c <= 0x6FF)
     139        return LanguageSpecificFont::Arabic;
     140    if (c < 0x900)
     141        return LanguageSpecificFont::None;
     142    if (c < 0xE00)
     143        return LanguageSpecificFont::Arabic;
     144    if (c <= 0xE7F)
     145        return LanguageSpecificFont::Thai;
     146    if (c < 0x0F00)
     147        return LanguageSpecificFont::Lao;
     148    if (c <= 0x0FFF)
     149        return LanguageSpecificFont::Tibetan;
     150    if (c < 0x1100)
     151        return LanguageSpecificFont::None;
     152    if (c <= 0x11FF)
     153        return LanguageSpecificFont::Korean;
     154    if (c > 0x1400 && c < 0x1780)
     155        return LanguageSpecificFont::CanadianAboriginalSyllabic;
     156    if (c < 0x1800)
     157        return LanguageSpecificFont::Khmer;
     158    if (c < 0x2E80)
     159        return LanguageSpecificFont::None;
     160    if (c < 0x3130)
     161        return LanguageSpecificFont::ChineseJapanese;
     162    if (c <= 0x318F)
     163        return LanguageSpecificFont::Korean;
     164    if (c < 0xAC00)
     165        return LanguageSpecificFont::ChineseJapanese;
     166    if (c <= 0xD7A3)
     167        return LanguageSpecificFont::Korean;
     168    if (c <= 0xDFFF)
     169        return LanguageSpecificFont::ChineseJapanese;
     170    if (c < 0xE000)
     171        return LanguageSpecificFont::None;
     172    if (c < 0xE600)
     173        return isGB18030ComplianceRequired ? LanguageSpecificFont::ChineseJapanese : LanguageSpecificFont::Emoji;
     174    if (c <= 0xE864 && isGB18030ComplianceRequired)
     175        return LanguageSpecificFont::ChineseJapanese;
     176    if (c <= 0xF8FF)
     177        return LanguageSpecificFont::None;
     178    if (c < 0xFB00)
     179        return LanguageSpecificFont::ChineseJapanese;
     180    if (c < 0xFB50)
     181        return LanguageSpecificFont::None;
     182    if (c <= 0xFDFF)
     183        return LanguageSpecificFont::Arabic;
     184    if (c < 0xFE20)
     185        return LanguageSpecificFont::None;
     186    if (c < 0xFE70)
     187        return LanguageSpecificFont::ChineseJapanese;
     188    if (c < 0xFF00)
     189        return LanguageSpecificFont::Arabic;
     190    if (c < 0xFFF0)
     191        return LanguageSpecificFont::ChineseJapanese;
     192    if (c >=0x20000 && c <= 0x2FFFF)
     193        return LanguageSpecificFont::ChineseJapanese;
     194    return LanguageSpecificFont::None;
     195}
     196
    102197PassRefPtr<SimpleFontData> FontCache::systemFallbackForCharacters(const FontDescription& description, const SimpleFontData* originalFontData, bool, const UChar* characters, int length)
    103198{
    104     static bool isGB18030ComplianceRequired = wkIsGB18030ComplianceRequired();
    105 
    106199    // Unlike OS X, our fallback font on iPhone is Arial Unicode, which doesn't have some apple-specific glyphs like F8FF.
    107200    // Fall back to the Apple Fallback font in this case.
     
    120213    }
    121214
    122     bool useCJFont = false;
    123     bool useKoreanFont = false;
    124     bool useCyrillicFont = false;
    125     bool useArabicFont = false;
    126     bool useHebrewFont = false;
    127     bool useIndicFont = false;
    128     bool useThaiFont = false;
    129     bool useTibetanFont = false;
    130     bool useCanadianAboriginalSyllabicsFont = false;
    131     bool useEmojiFont = false;
    132     if (length > 0) {
    133         do {
    134             // This isn't a loop but a way to efficiently check for ranges of characters.
    135 
    136             // The following ranges are Korean Hangul and should be rendered by AppleSDGothicNeo
    137             // U+1100 - U+11FF
    138             // U+3130 - U+318F
    139             // U+AC00 - U+D7A3
    140 
    141             // These are Cyrillic and should be rendered by Helvetica Neue
    142             // U+0400 - U+052F
    143 
    144             if (c < 0x400)
    145                 break;
    146             if (c <= 0x52F) {
    147                 useCyrillicFont = true;
    148                 break;
    149             }
    150             if (c < 0x590)
    151                 break;
    152             if (c < 0x600) {
    153                 useHebrewFont = true;
    154                 break;
    155             }
    156             if (c <= 0x6FF) {
    157                 useArabicFont = true;
    158                 break;
    159             }
    160             if (c < 0x900)
    161                 break;
    162             if (c < 0xE00) {
    163                 useIndicFont = true;
    164                 break;
    165             }
    166             if (c <= 0xE7F) {
    167                 useThaiFont = true;
    168                 break;
    169             }
    170             if (c < 0x0F00)
    171                 break;
    172             if (c <= 0x0FFF) {
    173                 useTibetanFont = true;
    174                 break;
    175             }
    176             if (c < 0x1100)
    177                 break;
    178             if (c <= 0x11FF) {
    179                 useKoreanFont = true;
    180                 break;
    181             }
    182             if (c > 0x1400 && c < 0x1780) {
    183                 useCanadianAboriginalSyllabicsFont = true;
    184                 break;
    185             }
    186             if (c < 0x2E80)
    187                 break;
    188             if (c < 0x3130) {
    189                 useCJFont = true;
    190                 break;
    191             }
    192             if (c <= 0x318F) {
    193                 useKoreanFont = true;
    194                 break;
    195             }
    196             if (c < 0xAC00) {
    197                 useCJFont = true;
    198                 break;
    199             }
    200             if (c <= 0xD7A3) {
    201                 useKoreanFont = true;
    202                 break;
    203             }
    204             if ( c <= 0xDFFF) {
    205                 useCJFont = true;
    206                 break;
    207             }
    208             if ( c < 0xE000)
    209                 break;
    210             if ( c < 0xE600) {
    211                 if (isGB18030ComplianceRequired)
    212                     useCJFont = true;
    213                 else
    214                     useEmojiFont = true;
    215                 break;
    216             }
    217             if ( c <= 0xE864 && isGB18030ComplianceRequired) {
    218                 useCJFont = true;
    219                 break;
    220             }
    221             if (c <= 0xF8FF)
    222                 break;
    223             if (c < 0xFB00) {
    224                 useCJFont = true;
    225                 break;
    226             }
    227             if (c < 0xFB50)
    228                 break;
    229             if (c <= 0xFDFF) {
    230                 useArabicFont = true;
    231                 break;
    232             }
    233             if (c < 0xFE20)
    234                 break;
    235             if (c < 0xFE70) {
    236                 useCJFont = true;
    237                 break;
    238             }
    239             if (c < 0xFF00) {
    240                 useArabicFont = true;
    241                 break;
    242             }
    243             if (c < 0xFFF0) {
    244                 useCJFont = true;
    245                 break;
    246             }
    247             if (c >=0x20000 && c <= 0x2FFFF)
    248                 useCJFont = true;
    249         } while (0);
    250     }
     215    LanguageSpecificFont languageSpecificFont = LanguageSpecificFont::None;
     216    if (length > 0)
     217        languageSpecificFont = languageSpecificFallbackFont(c);
    251218
    252219    RefPtr<SimpleFontData> simpleFontData;
    253220
    254     if (useCJFont) {
     221    switch (languageSpecificFont) {
     222    case LanguageSpecificFont::ChineseJapanese: {
    255223        // By default, Chinese font is preferred, fall back on Japanese.
    256224
     
    340308        if (useSecondaryFont)
    341309            simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? *cjkBold[secondaryCJKFont] : *cjkPlain[secondaryCJKFont], false, DoNotRetain);
    342     } else if (useKoreanFont) {
     310        break;
     311    }
     312    case LanguageSpecificFont::Korean: {
    343313        static NeverDestroyed<AtomicString> koreanPlain("AppleSDGothicNeo-Medium", AtomicString::ConstructFromLiteral);
    344314        static NeverDestroyed<AtomicString> koreanBold("AppleSDGothicNeo-Bold", AtomicString::ConstructFromLiteral);
    345315        simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? koreanBold : koreanPlain, false, DoNotRetain);
    346     } else if (useCyrillicFont) {
     316        break;
     317    }
     318    case LanguageSpecificFont::Cyrillic: {
    347319        static NeverDestroyed<AtomicString> cyrillicPlain("HelveticaNeue", AtomicString::ConstructFromLiteral);
    348320        static NeverDestroyed<AtomicString> cyrillicBold("HelveticaNeue-Bold", AtomicString::ConstructFromLiteral);
    349321        simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? cyrillicBold : cyrillicPlain, false, DoNotRetain);
    350     } else if (useArabicFont) {
     322        break;
     323    }
     324    case LanguageSpecificFont::Arabic: {
    351325        static NeverDestroyed<AtomicString> arabicPlain("GeezaPro", AtomicString::ConstructFromLiteral);
    352326        static NeverDestroyed<AtomicString> arabicBold("GeezaPro-Bold", AtomicString::ConstructFromLiteral);
    353327        simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? arabicBold : arabicPlain, false, DoNotRetain);
    354     } else if (useHebrewFont) {
     328        break;
     329    }
     330    case LanguageSpecificFont::Hebrew: {
    355331        static NeverDestroyed<AtomicString> hebrewPlain("ArialHebrew", AtomicString::ConstructFromLiteral);
    356332        static NeverDestroyed<AtomicString> hebrewBold("ArialHebrew-Bold", AtomicString::ConstructFromLiteral);
    357333        simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? hebrewBold : hebrewPlain, false, DoNotRetain);
    358     } else if (useIndicFont) {
     334        break;
     335    }
     336    case LanguageSpecificFont::Indic: {
    359337        static NeverDestroyed<AtomicString> devanagariFont("KohinoorDevanagari-Book", AtomicString::ConstructFromLiteral);
    360338        static NeverDestroyed<AtomicString> bengaliFont("BanglaSangamMN", AtomicString::ConstructFromLiteral);
     
    411389                simpleFontData = getCachedFontData(description, *indicFontString, false, DoNotRetain);
    412390        }
    413     } else if (useThaiFont) {
     391        break;
     392    }
     393    case LanguageSpecificFont::Thai: {
    414394        static NeverDestroyed<AtomicString> thaiPlain("Thonburi", AtomicString::ConstructFromLiteral);
    415395        static NeverDestroyed<AtomicString> thaiBold("Thonburi-Bold", AtomicString::ConstructFromLiteral);
    416396        simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? thaiBold : thaiPlain, false, DoNotRetain);
    417     } else if (useTibetanFont) {
     397        break;
     398    }
     399    case LanguageSpecificFont::Tibetan: {
    418400        static NeverDestroyed<AtomicString> tibetanPlain("Kailasa", AtomicString::ConstructFromLiteral);
    419401        static NeverDestroyed<AtomicString> tibetanBold("Kailasa-Bold", AtomicString::ConstructFromLiteral);
    420402        simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? tibetanBold : tibetanPlain, false, DoNotRetain);
    421     } else if (useCanadianAboriginalSyllabicsFont) {
     403        break;
     404    }
     405    case LanguageSpecificFont::CanadianAboriginalSyllabic: {
    422406        static NeverDestroyed<AtomicString> casPlain("EuphemiaUCAS", AtomicString::ConstructFromLiteral);
    423407        static NeverDestroyed<AtomicString> casBold("EuphemiaUCAS-Bold", AtomicString::ConstructFromLiteral);
    424408        simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? casBold : casPlain, false, DoNotRetain);
    425     } else {
     409        break;
     410    }
     411    case LanguageSpecificFont::Khmer: {
     412        static NeverDestroyed<AtomicString> khmer("KhmerSangamMN", AtomicString::ConstructFromLiteral);
     413        simpleFontData = getCachedFontData(description, khmer, false, DoNotRetain);
     414        break;
     415    }
     416    case LanguageSpecificFont::Lao: {
     417        static NeverDestroyed<AtomicString> lao("LaoSangamMN", AtomicString::ConstructFromLiteral);
     418        simpleFontData = getCachedFontData(description, lao, false, DoNotRetain);
     419        break;
     420    }
     421    default: {
    426422        static NeverDestroyed<AtomicString> appleColorEmoji("AppleColorEmoji", AtomicString::ConstructFromLiteral);
     423        bool useEmojiFont = languageSpecificFont == LanguageSpecificFont::Emoji;
    427424        if (!useEmojiFont) {
    428425            if (!CFCharacterSetIsLongCharacterMember(phoneFallbackCharacterSet(), c))
     
    431428        if (useEmojiFont)
    432429            simpleFontData = getCachedFontData(description, appleColorEmoji, false, DoNotRetain);
     430        break;
     431    }
    433432    }
    434433
Note: See TracChangeset for help on using the changeset viewer.