PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const { FontDescription desc = FontDescription(fontDescription); desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize()); FontPlatformData fontPlatformData(desc, desc.family().family()); return adoptPtr(new SimpleFontData(fontPlatformData, isCustomFont(), false)); }
FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& fontDescription, bool bold, bool italic) { int size = fontDescription.computedPixelSize(); FontRenderingMode renderingMode = fontDescription.renderingMode(); LOGFONT logFont; memset(&logFont, 0, sizeof(LOGFONT)); wcsncpy(logFont.lfFaceName, m_name.charactersWithNullTermination().data(), LF_FACESIZE - 1); logFont.lfHeight = -size; if (renderingMode == FontRenderingMode::Normal) logFont.lfHeight *= 32; logFont.lfWidth = 0; logFont.lfEscapement = 0; logFont.lfOrientation = 0; logFont.lfUnderline = false; logFont.lfStrikeOut = false; logFont.lfCharSet = DEFAULT_CHARSET; logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS; logFont.lfQuality = CLEARTYPE_QUALITY; logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; logFont.lfItalic = italic; logFont.lfWeight = bold ? 700 : 400; auto hfont = adoptGDIObject(::CreateFontIndirect(&logFont)); cairo_font_face_t* fontFace = cairo_win32_font_face_create_for_hfont(hfont.get()); FontPlatformData fontPlatformData(WTFMove(hfont), fontFace, size, bold, italic); cairo_font_face_destroy(fontFace); return fontPlatformData; }
RefPtr<Font> CSSFontFaceSource::font(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, CSSFontSelector* fontSelector, const FontFeatureSettings& fontFaceFeatures, const FontVariantSettings& fontFaceVariantSettings) { // If the font hasn't loaded or an error occurred, then we've got nothing. if (!isValid()) return nullptr; if (!m_font #if ENABLE(SVG_FONTS) && !m_svgFontFaceElement #endif ) { // We're local. Just return a Font from the normal cache. // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter. return FontCache::singleton().fontForFamily(fontDescription, m_string, true); } if (!m_font || m_font->isLoaded()) { if (m_font) { if (!m_font->ensureCustomFontData(m_string)) return nullptr; return m_font->createFont(fontDescription, m_string, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings); } else { #if ENABLE(SVG_FONTS) // In-Document SVG Fonts if (m_svgFontFaceElement) { #if ENABLE(SVG_OTF_CONVERTER) if (!m_svgFontFaceElement->parentNode() || !is<SVGFontElement>(m_svgFontFaceElement->parentNode())) return nullptr; SVGFontElement& fontElement = downcast<SVGFontElement>(*m_svgFontFaceElement->parentNode()); // FIXME: Re-run this when script modifies the element or any of its descendents // FIXME: We might have already converted this font. Make existing conversions discoverable. if (auto otfFont = convertSVGToOTFFont(fontElement)) m_generatedOTFBuffer = SharedBuffer::adoptVector(otfFont.value()); if (!m_generatedOTFBuffer) return nullptr; auto customPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer); if (!customPlatformData) return nullptr; return Font::create(customPlatformData->fontPlatformData(fontDescription, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings), true, false); #else return Font::create(std::make_unique<SVGFontData>(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic); #endif } #endif return nullptr; } } else { // Kick off the load. Do it soon rather than now, because we may be in the middle of layout, // and the loader may invoke arbitrary delegate or event handler code. fontSelector->beginLoadingFontSoon(m_font.get()); return Font::create(FontCache::singleton().lastResortFallbackFont(fontDescription)->platformData(), true, true); } }
const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* chars, int length) { // The comments below are valid but we still need to support fallback fonts for sites out of our control (like a payment site for example). // So we need to send down a sample glyph with the fontDescription and prefered family name so that EAText can find an alternate font. // For example, several sites just use Times New Roman expecting that it will include Chinese fonts but our Time New Roman does not have it so // it drops back in here as a last resort. // Ideally, it would be great if we could pass down a sample glyph to EAText when we first get a font instead of just machting the family name/description. // Seems that other text implementations might be able to automatically replace a missing glyph with another font so they just return NULL here. // It may be better to have a leak free implementation here. See the commented out code below as example however that implementation does not pass // down a sample char so it is unable to confirm that the glyph is actually supported by the font. const FontDescription& fontDescription(font.fontDescription()); const AtomicString& fontFamily(font.family().family()); FontPlatformData fontPlatformData(fontDescription, fontFamily, chars, length); return new SimpleFontData(fontPlatformData); /* // Note by Arpit Baldeva: // This method is called when WebCore can not find the glyphs for the characters in the loaded font. This method is intended // to serve as a "fallback to available fonts in the system". Since we never want to load fonts ourselves(the application is // supposed to preload the fonts it needs), we simply return 0 here. #if 1 return 0; #else // In case, we need to implement this functionality, the leak free implementation is as follows. Following makes sure that the // created font ends up in a list that is freed at the Shutdown. const FontDescription& fontDescription(font.fontDescription()); const AtomicString& fontFamily(font.family().family()); FontPlatformData* platformData = getCachedFontPlatformData(font.fontDescription(), fontFamily, false); SimpleFontData* fontData = getCachedFontData(platformData); // ASSERT(fontData->containsCharacters(characters, length)); return fontData; #endif */ }
RefPtr<Font> CSSFontFaceSource::font(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, CSSFontSelector* fontSelector) { // If the font hasn't loaded or an error occurred, then we've got nothing. if (!isValid()) return nullptr; if (!m_font #if ENABLE(SVG_FONTS) && !m_svgFontFaceElement #endif ) { // We're local. Just return a Font from the normal cache. // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter. return FontCache::singleton().fontForFamily(fontDescription, m_string, true); } unsigned hashKey = (fontDescription.computedPixelSize() + 1) << 5 | fontDescription.widthVariant() << 3 | (fontDescription.orientation() == Vertical ? 4 : 0) | (syntheticBold ? 2 : 0) | (syntheticItalic ? 1 : 0); RefPtr<Font> font = m_fontTable.add(hashKey, nullptr).iterator->value; if (font) return font.release(); // If we are still loading, then we let the system pick a font. if (isLoaded()) { if (m_font) { // Create new FontPlatformData from our CGFontRef, point size and ATSFontRef. bool hasExternalSVGFont = false; #if ENABLE(SVG_FONTS) hasExternalSVGFont = m_hasExternalSVGFont; #endif if (!m_font->ensureCustomFontData(hasExternalSVGFont, m_string)) return nullptr; font = m_font->createFont(fontDescription, m_string, syntheticBold, syntheticItalic, hasExternalSVGFont); } else { #if ENABLE(SVG_FONTS) // In-Document SVG Fonts if (m_svgFontFaceElement) { #if ENABLE(SVG_OTF_CONVERTER) if (!m_svgFontFaceElement->parentNode() || !is<SVGFontElement>(m_svgFontFaceElement->parentNode())) return nullptr; SVGFontElement& fontElement = downcast<SVGFontElement>(*m_svgFontFaceElement->parentNode()); // FIXME: Re-run this when script modifies the element or any of its descendents // FIXME: We might have already converted this font. Make existing conversions discoverable. Vector<char> otfFont = convertSVGToOTFFont(fontElement); m_generatedOTFBuffer = SharedBuffer::adoptVector(otfFont); if (!m_generatedOTFBuffer) return nullptr; auto customPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer); if (!customPlatformData) return nullptr; font = Font::create(customPlatformData->fontPlatformData(fontDescription, syntheticBold, syntheticItalic), true, false); #else font = Font::create(std::make_unique<SVGFontData>(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic); #endif } #endif } } else { // Kick off the load. Do it soon rather than now, because we may be in the middle of layout, // and the loader may invoke arbitrary delegate or event handler code. fontSelector->beginLoadingFontSoon(m_font.get()); Ref<Font> placeholderFont = FontCache::singleton().lastResortFallbackFont(fontDescription); Ref<Font> placeholderFontCopyInLoadingState = Font::create(placeholderFont->platformData(), true, true); return WTF::move(placeholderFontCopyInLoadingState); } return font.release(); }