示例#1
0
// FIXME:
//  - Handle 'Inherited', 'Common' and 'Unknown'
//    (see http://www.unicode.org/reports/tr24/#Usage_Model )
//    For 'Inherited' and 'Common', perhaps we need to
//    accept another parameter indicating the previous family
//    and just return it.
//  - All the characters (or characters up to the point a single
//    font can cover) need to be taken into account
const UChar* getFallbackFamily(UChar32 character,
    FontDescription::GenericFamilyType generic,
    UScriptCode contentScript,
    const AtomicString& contentLocale,
    UScriptCode* scriptChecked,
    SkFontMgr* fontManager)
{
    ASSERT(character);
    ASSERT(fontManager);
    const UChar* family = getFontBasedOnUnicodeBlock(character, fontManager);
    if (family) {
        if (scriptChecked)
            *scriptChecked = USCRIPT_INVALID_CODE;
        return family;
    }

    UScriptCode script = getScript(character);

    // For the full-width ASCII characters (U+FF00 - U+FF5E), use the font for
    // Han (determined in a locale-dependent way above). Full-width ASCII
    // characters are rather widely used in Japanese and Chinese documents and
    // they're fully covered by Chinese, Japanese and Korean fonts.
    if (0xFF00 < character && character < 0xFF5F)
        script = USCRIPT_HAN;

    if (script == USCRIPT_COMMON)
        script = getScriptBasedOnUnicodeBlock(character);

    // For unified-Han scripts, try the lang attribute.
    if (script == USCRIPT_HAN) {
        if (isUnambiguousUnifiedHanScript(contentScript))
            script = contentScript;
        else
            script = scriptCodeForUnifiedHanFromSubtags(contentLocale);
    }

    family = getFontFamilyForScript(script, generic, fontManager);
    // Another lame work-around to cover non-BMP characters.
    // If the font family for script is not found or the character is
    // not in BMP (> U+FFFF), we resort to the hard-coded list of
    // fallback fonts for now.
    if (!family || character > 0xFFFF) {
        int plane = character >> 16;
        switch (plane) {
        case 1:
            family = L"code2001";
            break;
        case 2:
            // Use a Traditional Chinese ExtB font if in Traditional Chinese locale.
            // Otherwise, use a Simplified Chinese ExtB font. Windows Japanese
            // fonts do support a small subset of ExtB (that are included in JIS X 0213),
            // but its coverage is rather sparse.
            // Eventually, this should be controlled by lang/xml:lang.
            if (icu::Locale::getDefault() == icu::Locale::getTraditionalChinese())
                family = L"pmingliu-extb";
            else
                family = L"simsun-extb";
            break;
        default:
            family = L"lucida sans unicode";
        }
    }
// FIXME:
//  - Handle 'Inherited', 'Common' and 'Unknown'
//    (see http://www.unicode.org/reports/tr24/#Usage_Model )
//    For 'Inherited' and 'Common', perhaps we need to
//    accept another parameter indicating the previous family
//    and just return it.
//  - All the characters (or characters up to the point a single
//    font can cover) need to be taken into account
const UChar* getFallbackFamily(const UChar* characters,
                               int length,
                               FontDescription::GenericFamilyType generic,
                               UChar32* charChecked,
                               UScriptCode* scriptChecked)
{
    ASSERT(characters && characters[0] && length > 0);
    UScriptCode script = USCRIPT_COMMON;

    // Sometimes characters common to script (e.g. space) is at
    // the beginning of a string so that we need to skip them
    // to get a font required to render the string.
    int i = 0;
    UChar32 ucs4 = 0;
    while (i < length && script == USCRIPT_COMMON || script == USCRIPT_INVALID_CODE) {
        U16_NEXT(characters, i, length, ucs4);
        UErrorCode err = U_ZERO_ERROR;
        script = uscript_getScript(ucs4, &err);
        // silently ignore the error
    }

    // For the full-width ASCII characters (U+FF00 - U+FF5E), use the font for
    // Han (determined in a locale-dependent way above). Full-width ASCII
    // characters are rather widely used in Japanese and Chinese documents and
    // they're fully covered by Chinese, Japanese and Korean fonts.
    if (0xFF00 < ucs4 && ucs4 < 0xFF5F)
        script = USCRIPT_HAN;

    // There are a lot of characters in USCRIPT_COMMON that can be covered
    // by fonts for scripts closely related to them. See
    // http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:Script=Common:]
    // FIXME: make this more efficient with a wider coverage
    if (script == USCRIPT_COMMON || script == USCRIPT_INHERITED) {
        UBlockCode block = ublock_getCode(ucs4);
        switch (block) {
        case UBLOCK_BASIC_LATIN:
            script = USCRIPT_LATIN;
            break;
        case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION:
            script = USCRIPT_HAN;
            break;
        case UBLOCK_HIRAGANA:
        case UBLOCK_KATAKANA:
            script = USCRIPT_HIRAGANA;
            break;
        case UBLOCK_ARABIC:
            script = USCRIPT_ARABIC;
            break;
        case UBLOCK_GREEK:
            script = USCRIPT_GREEK;
            break;
        case UBLOCK_DEVANAGARI:
            // For Danda and Double Danda (U+0964, U+0965), use a Devanagari
            // font for now although they're used by other scripts as well.
            // Without a context, we can't do any better.
            script = USCRIPT_DEVANAGARI;
            break;
        case UBLOCK_ARMENIAN:
            script = USCRIPT_ARMENIAN;
            break;
        case UBLOCK_GEORGIAN:
            script = USCRIPT_GEORGIAN;
            break;
        case UBLOCK_KANNADA:
            script = USCRIPT_KANNADA;
            break;
        }
    }

    // Another lame work-around to cover non-BMP characters.
    const UChar* family = getFontFamilyForScript(script, generic);
    if (!family) {
        int plane = ucs4 >> 16;
        switch (plane) {
        case 1:
            family = L"code2001";
            break;
        case 2:
            family = L"simsun-extb";
            break;
        default:
            family = L"lucida sans unicode";
        }
    }