GlyphData FontCascadeFonts::glyphDataForNormalVariant(UChar32 c, const FontCascadeDescription& description) { for (unsigned fallbackIndex = 0; ; ++fallbackIndex) { auto& fontRanges = realizeFallbackRangesAt(description, fallbackIndex); if (fontRanges.isNull()) break; GlyphData data = fontRanges.glyphDataForCharacter(c); if (!data.font) continue; if (data.font->platformData().orientation() == Vertical && !data.font->isTextOrientationFallback()) { if (!FontCascade::isCJKIdeographOrSymbol(c)) return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data); if (!data.font->hasVerticalGlyphs()) { // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs // to make sure you get a square (even for broken glyphs like symbols used for punctuation). return glyphDataForVariant(c, description, BrokenIdeographVariant, fallbackIndex); } #if PLATFORM(COCOA) || USE(CAIRO) if (data.font->platformData().syntheticOblique()) return glyphDataForCJKCharacterWithoutSyntheticItalic(c, data); #endif } return data; } return glyphDataForSystemFallback(c, description, NormalVariant); }
GlyphData FontCascadeFonts::glyphDataForSystemFallback(UChar32 c, const FontCascadeDescription& description, FontVariant variant) { // System fallback is character-dependent. auto& primaryRanges = realizeFallbackRangesAt(description, 0); auto* originalFont = primaryRanges.fontForCharacter(c); if (!originalFont) originalFont = &primaryRanges.fontForFirstRange(); auto 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 (fallbackGlyphData.font && fallbackGlyphData.font->platformData().orientation() == Vertical && !fallbackGlyphData.font->isTextOrientationFallback()) { if (variant == NormalVariant && !FontCascade::isCJKIdeographOrSymbol(c)) fallbackGlyphData = glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), fallbackGlyphData); #if PLATFORM(COCOA) || USE(CAIRO) if (fallbackGlyphData.font->platformData().syntheticOblique() && FontCascade::isCJKIdeographOrSymbol(c)) fallbackGlyphData = glyphDataForCJKCharacterWithoutSyntheticItalic(c, fallbackGlyphData); #endif } // Keep the system fallback fonts we use alive. if (fallbackGlyphData.glyph) m_systemFallbackFontSet.add(WTFMove(systemFallbackFont)); return fallbackGlyphData; }