Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: third_party/WebKit/Source/platform/fonts/win/FontFallbackWin.cpp

Issue 1607943004: Change the system font fallback to take lang attributes into account on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix TestExpectations for the new test Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2006, 2007, 2008, 2009, 2010, 2012 Google Inc. All rights reser ved. 2 * Copyright (c) 2006, 2007, 2008, 2009, 2010, 2012 Google Inc. All rights reser ved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 24 matching lines...) Expand all
35 #include "SkTypeface.h" 35 #include "SkTypeface.h"
36 #include "wtf/HashMap.h" 36 #include "wtf/HashMap.h"
37 #include "wtf/StringExtras.h" 37 #include "wtf/StringExtras.h"
38 #include "wtf/text/StringHash.h" 38 #include "wtf/text/StringHash.h"
39 #include "wtf/text/WTFString.h" 39 #include "wtf/text/WTFString.h"
40 #include <limits> 40 #include <limits>
41 #include <unicode/uchar.h> 41 #include <unicode/uchar.h>
42 42
43 namespace blink { 43 namespace blink {
44 44
45 static bool isUnambiguousUnifiedHanScript(UScriptCode script)
46 {
47 // localeToScriptCodeForFontSelection() does not return these values.
48 ASSERT(script != USCRIPT_HIRAGANA && script != USCRIPT_KATAKANA);
49 return script == USCRIPT_KATAKANA_OR_HIRAGANA
50 || script == USCRIPT_SIMPLIFIED_HAN
51 || script == USCRIPT_TRADITIONAL_HAN
52 || script == USCRIPT_HANGUL;
53 }
54
55 static UScriptCode scriptCodeForUnifiedHanFromSubtag(const String& subtag)
56 {
57 struct SubtagScript {
58 const char* subtag;
59 UScriptCode script;
60 };
61
62 static const SubtagScript subtagScriptList[] = {
63 { "cn", USCRIPT_SIMPLIFIED_HAN },
64 { "hans", USCRIPT_SIMPLIFIED_HAN },
65 { "hant", USCRIPT_TRADITIONAL_HAN },
66 { "hk", USCRIPT_TRADITIONAL_HAN },
67 { "jp", USCRIPT_HIRAGANA },
68 { "kr", USCRIPT_HANGUL },
69 { "tw", USCRIPT_TRADITIONAL_HAN },
70 };
71
72 typedef HashMap<String, UScriptCode> SubtagScriptMap;
73 DEFINE_STATIC_LOCAL(SubtagScriptMap, subtagScriptMap, ());
74 if (subtagScriptMap.isEmpty()) {
75 for (size_t i = 0; i < WTF_ARRAY_LENGTH(subtagScriptList); ++i)
76 subtagScriptMap.set(subtagScriptList[i].subtag, subtagScriptList[i]. script);
77 }
78
79 const auto& it = subtagScriptMap.find(subtag.lower());
80 return it != subtagScriptMap.end() ? it->value : USCRIPT_COMMON;
81 }
82
83 UScriptCode scriptCodeForUnifiedHanFromSubtags(const String& locale)
84 {
85 // Some sites emit lang="en-JP" when English is set as the preferred
86 // language. Use script/region subtags of the content locale to pick the
87 // fallback font for unified Han ideographs.
88 for (size_t delimiter = locale.find('-'); delimiter != kNotFound; ) {
89 ++delimiter;
90 size_t end = locale.find('-', delimiter);
91 UScriptCode script = scriptCodeForUnifiedHanFromSubtag(
92 locale.substring(delimiter,
93 end == kNotFound ? UINT_MAX : end - delimiter));
94 if (script != USCRIPT_COMMON)
95 return script;
96 delimiter = end;
97 }
98
99 // Fallback to the UI locale.
100 return USCRIPT_HAN;
101 }
102
45 UScriptCode scriptCodeForUnifiedHanFromLocale(const icu::Locale& locale) 103 UScriptCode scriptCodeForUnifiedHanFromLocale(const icu::Locale& locale)
46 { 104 {
47 // ICU default locale may have country as an empty string or differently. 105 // ICU default locale may have country as an empty string or differently.
48 // Avoid fullName comparisons for Japanese and Korean where language() 106 // Avoid fullName comparisons for Japanese and Korean where language()
49 // can safely disambiguate. 107 // can safely disambiguate.
50 if (strcasecmp(locale.getLanguage(), icu::Locale::getJapanese().getLanguage( )) == 0) 108 if (strcasecmp(locale.getLanguage(), icu::Locale::getJapanese().getLanguage( )) == 0)
51 return USCRIPT_HIRAGANA; 109 return USCRIPT_HIRAGANA;
52 if (strcasecmp(locale.getLanguage(), icu::Locale::getKorean().getLanguage()) == 0) 110 if (strcasecmp(locale.getLanguage(), icu::Locale::getKorean().getLanguage()) == 0)
53 return USCRIPT_HANGUL; 111 return USCRIPT_HANGUL;
54 112
55 const icu::Locale& traditionalChinese = icu::Locale::getTraditionalChinese() ; 113 // Chinese and non-CJK languages may be able to determine from subtags.
56 if (strcasecmp(locale.getLanguage(), traditionalChinese.getLanguage()) == 0 114 UScriptCode script = scriptCodeForUnifiedHanFromSubtag(locale.getScript());
57 && (strcasecmp(locale.getCountry(), traditionalChinese.getCountry()) == 0 115 if (script != USCRIPT_COMMON)
58 || strcasecmp(locale.getCountry(), "HK") == 0 116 return script;
59 || strcasecmp(locale.getScript(), "Hant") == 0)) { 117 script = scriptCodeForUnifiedHanFromSubtag(locale.getCountry());
60 return USCRIPT_TRADITIONAL_HAN; 118 if (script != USCRIPT_COMMON)
61 } 119 return script;
62 120
63 // For other locales, use the simplified Chinese font for Han. 121 // For other locales, use the simplified Chinese font for Han.
64 return USCRIPT_SIMPLIFIED_HAN; 122 return USCRIPT_SIMPLIFIED_HAN;
65 } 123 }
66 124
67 namespace { 125 namespace {
68 126
69 static inline bool isFontPresent(const UChar* fontName, SkFontMgr* fontManager) 127 static inline bool isFontPresent(const UChar* fontName, SkFontMgr* fontManager)
70 { 128 {
71 String family = fontName; 129 String family = fontName;
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 // FIXME: 452 // FIXME:
395 // - Handle 'Inherited', 'Common' and 'Unknown' 453 // - Handle 'Inherited', 'Common' and 'Unknown'
396 // (see http://www.unicode.org/reports/tr24/#Usage_Model ) 454 // (see http://www.unicode.org/reports/tr24/#Usage_Model )
397 // For 'Inherited' and 'Common', perhaps we need to 455 // For 'Inherited' and 'Common', perhaps we need to
398 // accept another parameter indicating the previous family 456 // accept another parameter indicating the previous family
399 // and just return it. 457 // and just return it.
400 // - All the characters (or characters up to the point a single 458 // - All the characters (or characters up to the point a single
401 // font can cover) need to be taken into account 459 // font can cover) need to be taken into account
402 const UChar* getFallbackFamily(UChar32 character, 460 const UChar* getFallbackFamily(UChar32 character,
403 FontDescription::GenericFamilyType generic, 461 FontDescription::GenericFamilyType generic,
462 UScriptCode contentScript,
463 const AtomicString& contentLocale,
404 UScriptCode* scriptChecked, 464 UScriptCode* scriptChecked,
405 SkFontMgr* fontManager) 465 SkFontMgr* fontManager)
406 { 466 {
407 ASSERT(character); 467 ASSERT(character);
408 ASSERT(fontManager); 468 ASSERT(fontManager);
409 const UChar* family = getFontBasedOnUnicodeBlock(character, fontManager); 469 const UChar* family = getFontBasedOnUnicodeBlock(character, fontManager);
410 if (family) { 470 if (family) {
411 if (scriptChecked) 471 if (scriptChecked)
412 *scriptChecked = USCRIPT_INVALID_CODE; 472 *scriptChecked = USCRIPT_INVALID_CODE;
413 return family; 473 return family;
414 } 474 }
415 475
416 UScriptCode script = getScript(character); 476 UScriptCode script = getScript(character);
417 477
418 // For the full-width ASCII characters (U+FF00 - U+FF5E), use the font for 478 // For the full-width ASCII characters (U+FF00 - U+FF5E), use the font for
419 // Han (determined in a locale-dependent way above). Full-width ASCII 479 // Han (determined in a locale-dependent way above). Full-width ASCII
420 // characters are rather widely used in Japanese and Chinese documents and 480 // characters are rather widely used in Japanese and Chinese documents and
421 // they're fully covered by Chinese, Japanese and Korean fonts. 481 // they're fully covered by Chinese, Japanese and Korean fonts.
422 if (0xFF00 < character && character < 0xFF5F) 482 if (0xFF00 < character && character < 0xFF5F)
423 script = USCRIPT_HAN; 483 script = USCRIPT_HAN;
424 484
425 if (script == USCRIPT_COMMON) 485 if (script == USCRIPT_COMMON)
426 script = getScriptBasedOnUnicodeBlock(character); 486 script = getScriptBasedOnUnicodeBlock(character);
427 487
488 // For unified-Han scripts, try the lang attribute.
489 if (script == USCRIPT_HAN) {
490 if (isUnambiguousUnifiedHanScript(contentScript))
491 script = contentScript;
492 else
493 script = scriptCodeForUnifiedHanFromSubtags(contentLocale);
494 }
495
428 family = getFontFamilyForScript(script, generic, fontManager); 496 family = getFontFamilyForScript(script, generic, fontManager);
429 // Another lame work-around to cover non-BMP characters. 497 // Another lame work-around to cover non-BMP characters.
430 // If the font family for script is not found or the character is 498 // If the font family for script is not found or the character is
431 // not in BMP (> U+FFFF), we resort to the hard-coded list of 499 // not in BMP (> U+FFFF), we resort to the hard-coded list of
432 // fallback fonts for now. 500 // fallback fonts for now.
433 if (!family || character > 0xFFFF) { 501 if (!family || character > 0xFFFF) {
434 int plane = character >> 16; 502 int plane = character >> 16;
435 switch (plane) { 503 switch (plane) {
436 case 1: 504 case 1:
437 family = L"code2001"; 505 family = L"code2001";
(...skipping 13 matching lines...) Expand all
451 family = L"lucida sans unicode"; 519 family = L"lucida sans unicode";
452 } 520 }
453 } 521 }
454 522
455 if (scriptChecked) 523 if (scriptChecked)
456 *scriptChecked = script; 524 *scriptChecked = script;
457 return family; 525 return family;
458 } 526 }
459 527
460 } // namespace blink 528 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698