PassRefPtr<FontData> CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription) { if (!isValid()) return nullptr; FontTraits desiredTraits = fontDescription.traits(); FontCacheKey key = fontDescription.cacheKey(FontFaceCreationParams(), desiredTraits); RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(key.hash(), nullptr).storedValue->value; if (fontData && fontData->numFaces()) return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has. if (!fontData) fontData = SegmentedFontData::create(); FontDescription requestedFontDescription(fontDescription); requestedFontDescription.setTraits(m_traits); requestedFontDescription.setSyntheticBold(m_traits.weight() < FontWeight600 && desiredTraits.weight() >= FontWeight600); requestedFontDescription.setSyntheticItalic(m_traits.style() == FontStyleNormal && desiredTraits.style() == FontStyleItalic); for (FontFaceList::reverse_iterator it = m_fontFaces.rbegin(); it != m_fontFaces.rend(); ++it) { if (!(*it)->cssFontFace()->isValid()) continue; if (RefPtr<SimpleFontData> faceFontData = (*it)->cssFontFace()->getFontData(requestedFontDescription)) { ASSERT(!faceFontData->isSegmented()); fontData->appendFace(FontDataForRangeSet(faceFontData.release(), (*it)->cssFontFace()->ranges())); } } if (fontData->numFaces()) return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has. return nullptr; }
PassRefPtr<FontData> CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription) { if (!isValid()) return nullptr; FontTraitsMask desiredTraitsMask = fontDescription.traitsMask(); AtomicString emptyFontFamily = ""; FontCacheKey key = fontDescription.cacheKey(emptyFontFamily, desiredTraitsMask); RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(key.hash(), nullptr).storedValue->value; if (fontData && fontData->numRanges()) return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has. if (!fontData) fontData = SegmentedFontData::create(); FontDescription requestedFontDescription(fontDescription); requestedFontDescription.setTraitsMask(m_traitsMask); requestedFontDescription.setSyntheticBold(!(m_traitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)) && (desiredTraitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask))); requestedFontDescription.setSyntheticItalic(!(m_traitsMask & FontStyleItalicMask) && (desiredTraitsMask & FontStyleItalicMask)); for (FontFaceList::reverse_iterator it = m_fontFaces.rbegin(); it != m_fontFaces.rend(); ++it) { if (!(*it)->cssFontFace()->isValid()) continue; if (RefPtr<SimpleFontData> faceFontData = (*it)->cssFontFace()->getFontData(requestedFontDescription)) { ASSERT(!faceFontData->isSegmented()); #if ENABLE(SVG_FONTS) // For SVG Fonts that specify that they only support the "normal" variant, we will assume they are incapable // of small-caps synthesis and just ignore the font face. if (faceFontData->isSVGFont() && (desiredTraitsMask & FontVariantSmallCapsMask) && !(m_traitsMask & FontVariantSmallCapsMask)) continue; #endif appendFontData(fontData.get(), faceFontData.release(), (*it)->cssFontFace()->ranges()); } } if (fontData->numRanges()) return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has. return nullptr; }
PassRefPtr<SimpleFontData> CSSFontFaceSource::getFontData(const FontDescription& fontDescription) { // If the font hasn't loaded or an error occurred, then we've got nothing. if (!isValid()) return 0; if (isLocal()) { // We're local. Just return a SimpleFontData from the normal cache. // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter. RefPtr<SimpleFontData> fontData = FontCache::fontCache()->getFontData(fontDescription, m_string, true); m_histograms.recordLocalFont(fontData); return fontData; } // See if we have a mapping in our FontData cache. AtomicString emptyFontFamily = ""; FontCacheKey key = fontDescription.cacheKey(emptyFontFamily); RefPtr<SimpleFontData>& fontData = m_fontDataTable.add(key.hash(), 0).iterator->value; if (fontData) return fontData; // No release, because fontData is a reference to a RefPtr that is held in the m_fontDataTable. // If we are still loading, then we let the system pick a font. if (isLoaded()) { if (m_font) { #if ENABLE(SVG_FONTS) if (m_hasExternalSVGFont) { // For SVG fonts parse the external SVG document, and extract the <font> element. if (!m_font->ensureSVGFontData()) return 0; if (!m_externalSVGFontElement) { String fragmentIdentifier; size_t start = m_string.find('#'); if (start != kNotFound) fragmentIdentifier = m_string.string().substring(start + 1); m_externalSVGFontElement = m_font->getSVGFontById(fragmentIdentifier); } if (!m_externalSVGFontElement) return 0; SVGFontFaceElement* fontFaceElement = 0; // Select first <font-face> child for (Node* fontChild = m_externalSVGFontElement->firstChild(); fontChild; fontChild = fontChild->nextSibling()) { if (fontChild->hasTagName(SVGNames::font_faceTag)) { fontFaceElement = toSVGFontFaceElement(fontChild); break; } } if (fontFaceElement) { if (!m_svgFontFaceElement) { // We're created using a CSS @font-face rule, that means we're not associated with a SVGFontFaceElement. // Use the imported <font-face> tag as referencing font-face element for these cases. m_svgFontFaceElement = fontFaceElement; } fontData = SimpleFontData::create( SVGFontData::create(fontFaceElement), fontDescription.effectiveFontSize(), fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic()); } } else #endif { // Create new FontPlatformData from our CGFontRef, point size and ATSFontRef. if (!m_font->ensureCustomFontData()) return 0; fontData = SimpleFontData::create( m_font->platformDataFromCustomData(fontDescription.effectiveFontSize(), fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic(), fontDescription.orientation(), fontDescription.widthVariant()), CustomFontData::create(false)); } } else { #if ENABLE(SVG_FONTS) // In-Document SVG Fonts if (m_svgFontFaceElement) { fontData = SimpleFontData::create( SVGFontData::create(m_svgFontFaceElement.get()), fontDescription.effectiveFontSize(), fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic()); } #endif } } else { // This temporary font is not retained and should not be returned. FontCachePurgePreventer fontCachePurgePreventer; SimpleFontData* temporaryFont = FontCache::fontCache()->getNonRetainedLastResortFallbackFont(fontDescription); if (!temporaryFont) { ASSERT_NOT_REACHED(); return 0; } RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create(true); cssFontData->setCSSFontFaceSource(this); fontData = SimpleFontData::create(temporaryFont->platformData(), cssFontData); } return fontData; // No release, because fontData is a reference to a RefPtr that is held in the m_fontDataTable. }