Esempio n. 1
0
GlyphData Font::glyphDataForCharacter(UChar32 character) const
{
    auto* page = glyphPage(character / GlyphPage::size);
    if (!page)
        return GlyphData();
    return page->glyphDataForCharacter(character);
}
Esempio n. 2
0
GlyphData FontCascadeFonts::glyphDataForCharacter(UChar32 c, const FontDescription& description, FontVariant variant)
{
    ASSERT(isMainThread());
    ASSERT(variant != AutoVariant);

    if (variant != NormalVariant)
        return glyphDataForVariant(c, description, variant, 0);

    const unsigned pageNumber = c / GlyphPage::size;

    RefPtr<GlyphPage>& cachedPage = pageNumber ? m_cachedPages.add(pageNumber, nullptr).iterator->value : m_cachedPageZero;
    if (!cachedPage)
        cachedPage = glyphPageFromFontRanges(pageNumber, realizeFallbackRangesAt(description, 0));

    GlyphData glyphData = cachedPage ? cachedPage->glyphDataForCharacter(c) : GlyphData();
    if (!glyphData.glyph) {
        if (!cachedPage)
            cachedPage = GlyphPage::createForMixedFonts();
        else if (cachedPage->isImmutable())
            cachedPage = GlyphPage::createCopyForMixedFonts(*cachedPage);

        glyphData = glyphDataForNormalVariant(c, description);
        cachedPage->setGlyphDataForCharacter(c, glyphData.glyph, glyphData.font);
    }
    return glyphData;
}
Esempio n. 3
0
GlyphData FontCascadeFonts::glyphDataForSystemFallback(UChar32 c, const FontDescription& description, FontVariant variant)
{
    // System fallback is character-dependent.
    auto& primaryRanges = realizeFallbackRangesAt(description, 0);
    auto* originalFont = primaryRanges.fontForCharacter(c);
    if (!originalFont)
        originalFont = &primaryRanges.fontForFirstRange();

    RefPtr<Font> systemFallbackFont = originalFont->systemFallbackFontForCharacter(c, description, m_isForPlatformFont);
    if (!systemFallbackFont)
        return GlyphData();

    if (systemFallbackFont->platformData().orientation() == Vertical && !systemFallbackFont->hasVerticalGlyphs() && FontCascade::isCJKIdeographOrSymbol(c))
        variant = BrokenIdeographVariant;

    GlyphData fallbackGlyphData;
    if (variant == NormalVariant)
        fallbackGlyphData = systemFallbackFont->glyphDataForCharacter(c);
    else
        fallbackGlyphData = systemFallbackFont->variantFont(description, variant)->glyphDataForCharacter(c);

    if (variant == NormalVariant && fallbackGlyphData.font) {
        if (!FontCascade::isCJKIdeographOrSymbol(c) && fallbackGlyphData.font->platformData().orientation() == Vertical && !fallbackGlyphData.font->isTextOrientationFallback())
            fallbackGlyphData = glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), fallbackGlyphData);
    }

    // Keep the system fallback fonts we use alive.
    if (fallbackGlyphData.glyph)
        m_systemFallbackFontSet.add(systemFallbackFont.release());

    return fallbackGlyphData;
}
Esempio n. 4
0
GlyphData FontCascadeFonts::glyphDataForVariant(UChar32 c, const FontDescription& description, FontVariant variant, unsigned fallbackIndex)
{
    while (true) {
        auto& fontRanges = realizeFallbackRangesAt(description, fallbackIndex++);
        if (fontRanges.isNull())
            break;
        auto* font = fontRanges.fontForCharacter(c);
        GlyphData data = font ? font->glyphDataForCharacter(c) : GlyphData();
        if (data.font) {
            // The variantFont function should not normally return 0.
            // But if it does, we will just render the capital letter big.
            RefPtr<Font> variantFont = data.font->variantFont(description, variant);
            if (!variantFont)
                return data;

            return variantFont->glyphDataForCharacter(c);
        }
    }

    return glyphDataForSystemFallback(c, description, variant);
}