void FontFaceSet::faceFinished(CSSFontFace& face, CSSFontFace::Status newStatus) { if (!face.existingWrapper()) return; auto iterator = m_pendingPromises.find(face.existingWrapper()); if (iterator == m_pendingPromises.end()) return; for (auto& pendingPromise : iterator->value) { if (pendingPromise->hasReachedTerminalState) continue; if (newStatus == CSSFontFace::Status::Success) { if (pendingPromise->hasOneRef()) { pendingPromise->promise.resolve(pendingPromise->faces); pendingPromise->hasReachedTerminalState = true; } } else { ASSERT(newStatus == CSSFontFace::Status::Failure); pendingPromise->promise.reject(NETWORK_ERR); pendingPromise->hasReachedTerminalState = true; } } m_pendingPromises.remove(iterator); }
static bool fontFaceComparator(FontTraitsMask desiredTraitsMaskForComparison, const CSSFontFace& first, const CSSFontFace& second) { FontTraitsMask firstTraitsMask = first.traitsMask(); FontTraitsMask secondTraitsMask = second.traitsMask(); bool firstHasDesiredStyle = firstTraitsMask & desiredTraitsMaskForComparison & FontStyleMask; bool secondHasDesiredStyle = secondTraitsMask & desiredTraitsMaskForComparison & FontStyleMask; if (firstHasDesiredStyle != secondHasDesiredStyle) return firstHasDesiredStyle; if ((desiredTraitsMaskForComparison & FontStyleItalicMask) && !first.isLocalFallback() && !second.isLocalFallback()) { // Prefer a font that has indicated that it can only support italics to a font that claims to support // all styles. The specialized font is more likely to be the one the author wants used. bool firstRequiresItalics = (firstTraitsMask & FontStyleItalicMask) && !(firstTraitsMask & FontStyleNormalMask); bool secondRequiresItalics = (secondTraitsMask & FontStyleItalicMask) && !(secondTraitsMask & FontStyleNormalMask); if (firstRequiresItalics != secondRequiresItalics) return firstRequiresItalics; } if (secondTraitsMask & desiredTraitsMaskForComparison & FontWeightMask) return false; if (firstTraitsMask & desiredTraitsMaskForComparison & FontWeightMask) return true; // http://www.w3.org/TR/2011/WD-css3-fonts-20111004/#font-matching-algorithm says : // - If the desired weight is less than 400, weights below the desired weight are checked in descending order followed by weights above the desired weight in ascending order until a match is found. // - If the desired weight is greater than 500, weights above the desired weight are checked in ascending order followed by weights below the desired weight in descending order until a match is found. // - If the desired weight is 400, 500 is checked first and then the rule for desired weights less than 400 is used. // - If the desired weight is 500, 400 is checked first and then the rule for desired weights less than 400 is used. static const unsigned fallbackRuleSets = 9; static const unsigned rulesPerSet = 8; static const FontTraitsMask weightFallbackRuleSets[fallbackRuleSets][rulesPerSet] = { { FontWeight200Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight100Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight200Mask, FontWeight100Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight500Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight700Mask, FontWeight800Mask, FontWeight900Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }, { FontWeight800Mask, FontWeight900Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }, { FontWeight900Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }, { FontWeight800Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask } }; unsigned ruleSetIndex = 0; for (; !(desiredTraitsMaskForComparison & (1 << (FontWeight100Bit + ruleSetIndex))); ruleSetIndex++) { } const FontTraitsMask* weightFallbackRule = weightFallbackRuleSets[ruleSetIndex]; for (unsigned i = 0; i < rulesPerSet; ++i) { if (secondTraitsMask & weightFallbackRule[i]) return false; if (firstTraitsMask & weightFallbackRule[i]) return true; } return false; }
CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDescription, const AtomicString& family) { Vector<RefPtr<CSSFontFace> >* familyFontFaces = m_fontFaces.get(family); if (!familyFontFaces || familyFontFaces->isEmpty()) return 0; OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& segmentedFontFaceCache = m_fonts.add(family, nullptr).iterator->value; if (!segmentedFontFaceCache) segmentedFontFaceCache = adoptPtr(new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >); FontTraitsMask traitsMask = fontDescription.traitsMask(); RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).iterator->value; if (!face) { face = CSSSegmentedFontFace::create(this); // Collect all matching faces and sort them in order of preference. Vector<CSSFontFace*, 32> candidateFontFaces; for (int i = familyFontFaces->size() - 1; i >= 0; --i) { CSSFontFace* candidate = familyFontFaces->at(i).get(); unsigned candidateTraitsMask = candidate->traitsMask(); if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask)) continue; if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask)) continue; #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 as a candidate. if (candidate->hasSVGFontFaceSource() && (traitsMask & FontVariantSmallCapsMask) && !(candidateTraitsMask & FontVariantSmallCapsMask)) continue; #endif candidateFontFaces.append(candidate); } if (Vector<RefPtr<CSSFontFace> >* familyLocallyInstalledFontFaces = m_locallyInstalledFontFaces.get(family)) { unsigned numLocallyInstalledFontFaces = familyLocallyInstalledFontFaces->size(); for (unsigned i = 0; i < numLocallyInstalledFontFaces; ++i) { CSSFontFace* candidate = familyLocallyInstalledFontFaces->at(i).get(); unsigned candidateTraitsMask = candidate->traitsMask(); if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask)) continue; if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask)) continue; candidateFontFaces.append(candidate); } } desiredTraitsMaskForComparison = traitsMask; stable_sort(candidateFontFaces.begin(), candidateFontFaces.end(), compareFontFaces); unsigned numCandidates = candidateFontFaces.size(); for (unsigned i = 0; i < numCandidates; ++i) face->appendFontFace(candidateFontFaces[i]); } return face.get(); }
void CSSSegmentedFontFace::willUseRange(const blink::FontDescription& fontDescription, const blink::FontDataForRangeSet& rangeSet) { // Iterating backwards since later defined unicode-range faces override // previously defined ones, according to the CSS3 fonts module. // https://drafts.csswg.org/css-fonts/#composite-fonts for (FontFaceList::reverse_iterator it = m_fontFaces.rbegin(); it != m_fontFaces.rend(); ++it) { CSSFontFace* cssFontFace = (*it)->cssFontFace(); if (cssFontFace->maybeScheduleFontLoad(fontDescription, rangeSet)) break; } }
void FontFace::adopt(CSSFontFace& newFace) { m_backing->removeClient(*this); m_backing = newFace; m_backing->addClient(*this); newFace.setWrapper(*this); }
void CSSFontFaceSet::add(CSSFontFace& face) { ASSERT(!hasFace(face)); for (auto* client : m_clients) client->fontModified(); face.addClient(*this); m_cache.clear(); if (face.cssConnection()) m_faces.insert(m_facesPartitionIndex++, face); else m_faces.append(face); addToFacesLookupTable(face); if (face.status() == CSSFontFace::Status::Loading || face.status() == CSSFontFace::Status::TimedOut) incrementActiveCount(); }
void CSSFontFaceSet::addToFacesLookupTable(CSSFontFace& face) { if (!face.families()) return; for (auto& item : *face.families()) { String familyName = CSSFontFaceSet::familyNameFromPrimitive(downcast<CSSPrimitiveValue>(item.get())); if (familyName.isEmpty()) continue; auto addResult = m_facesLookupTable.add(familyName, Vector<Ref<CSSFontFace>>()); auto& familyFontFaces = addResult.iterator->value; if (addResult.isNewEntry) { // m_locallyInstalledFontFaces grows without bound, eventually encorporating every font installed on the system. // This is by design. registerLocalFontFacesForFamily(familyName); familyFontFaces = { }; } familyFontFaces.append(face); } }
void CSSFontFaceSet::remove(const CSSFontFace& face) { m_cache.clear(); for (auto* client : m_clients) client->fontModified(); if (face.families()) removeFromFacesLookupTable(face, *face.families()); for (size_t i = 0; i < m_faces.size(); ++i) { if (m_faces[i].ptr() == &face) { if (i < m_facesPartitionIndex) --m_facesPartitionIndex; m_faces[i]->removeClient(*this); m_faces.remove(i); if (face.status() == CSSFontFace::Status::Loading || face.status() == CSSFontFace::Status::TimedOut) decrementActiveCount(); return; } } ASSERT_NOT_REACHED(); }
FontData* CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName) { if (m_fontFaces.isEmpty()) { if (familyName.startsWith("-webkit-")) return fontDataForGenericFamily(m_document, fontDescription, familyName); if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont()) return fontDataForGenericFamily(m_document, fontDescription, "-webkit-standard"); return 0; } String family = familyName.string(); Vector<RefPtr<CSSFontFace> >* familyFontFaces = m_fontFaces.get(family); // If no face was found, then return 0 and let the OS come up with its best match for the name. if (!familyFontFaces || familyFontFaces->isEmpty()) { // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our // settings. if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont()) return fontDataForGenericFamily(m_document, fontDescription, "-webkit-standard"); return fontDataForGenericFamily(m_document, fontDescription, familyName); } OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& segmentedFontFaceCache = m_fonts.add(family, nullptr).first->second; if (!segmentedFontFaceCache) segmentedFontFaceCache = adoptPtr(new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >); FontTraitsMask traitsMask = fontDescription.traitsMask(); RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).first->second; if (!face) { face = CSSSegmentedFontFace::create(this); // Collect all matching faces and sort them in order of preference. Vector<CSSFontFace*, 32> candidateFontFaces; for (int i = familyFontFaces->size() - 1; i >= 0; --i) { CSSFontFace* candidate = familyFontFaces->at(i).get(); unsigned candidateTraitsMask = candidate->traitsMask(); if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask)) continue; if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask)) continue; #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 as a candidate. if (candidate->hasSVGFontFaceSource() && (traitsMask & FontVariantSmallCapsMask) && !(candidateTraitsMask & FontVariantSmallCapsMask)) continue; #endif candidateFontFaces.append(candidate); } if (Vector<RefPtr<CSSFontFace> >* familyLocallyInstalledFontFaces = m_locallyInstalledFontFaces.get(family)) { unsigned numLocallyInstalledFontFaces = familyLocallyInstalledFontFaces->size(); for (unsigned i = 0; i < numLocallyInstalledFontFaces; ++i) { CSSFontFace* candidate = familyLocallyInstalledFontFaces->at(i).get(); unsigned candidateTraitsMask = candidate->traitsMask(); if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask)) continue; if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask)) continue; candidateFontFaces.append(candidate); } } desiredTraitsMaskForComparison = traitsMask; stable_sort(candidateFontFaces.begin(), candidateFontFaces.end(), compareFontFaces); unsigned numCandidates = candidateFontFaces.size(); for (unsigned i = 0; i < numCandidates; ++i) face->appendFontFace(candidateFontFaces[i]); } // We have a face. Ask it for a font data. If it cannot produce one, it will fail, and the OS will take over. return face->getFontData(fontDescription); }
FontData* CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName) { if (m_fontFaces.isEmpty()) { if (familyName.startsWith("-webkit-")) return fontDataForGenericFamily(m_document, fontDescription, familyName); return 0; } String family = familyName.string(); #if ENABLE(SVG_FONTS) if (fontDescription.smallCaps()) family += "-webkit-svg-small-caps"; #endif Vector<RefPtr<CSSFontFace> >* familyFontFaces = m_fontFaces.get(family); // If no face was found, then return 0 and let the OS come up with its best match for the name. if (!familyFontFaces || familyFontFaces->isEmpty()) { // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our // settings. return fontDataForGenericFamily(m_document, fontDescription, familyName); } HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >* segmentedFontFaceCache = m_fonts.get(family); if (!segmentedFontFaceCache) { segmentedFontFaceCache = new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >; m_fonts.set(family, segmentedFontFaceCache); } FontTraitsMask traitsMask = fontDescription.traitsMask(); RefPtr<CSSSegmentedFontFace> face = segmentedFontFaceCache->get(traitsMask); if (!face) { face = CSSSegmentedFontFace::create(this); segmentedFontFaceCache->set(traitsMask, face); // Collect all matching faces and sort them in order of preference. Vector<CSSFontFace*, 32> candidateFontFaces; for (int i = familyFontFaces->size() - 1; i >= 0; --i) { CSSFontFace* candidate = familyFontFaces->at(i).get(); unsigned candidateTraitsMask = candidate->traitsMask(); if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask)) continue; if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask)) continue; candidateFontFaces.append(candidate); } if (Vector<RefPtr<CSSFontFace> >* familyLocallyInstalledFontFaces = m_locallyInstalledFontFaces.get(family)) { unsigned numLocallyInstalledFontFaces = familyLocallyInstalledFontFaces->size(); for (unsigned i = 0; i < numLocallyInstalledFontFaces; ++i) { CSSFontFace* candidate = familyLocallyInstalledFontFaces->at(i).get(); unsigned candidateTraitsMask = candidate->traitsMask(); if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask)) continue; if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask)) continue; candidateFontFaces.append(candidate); } } desiredTraitsMaskForComparison = traitsMask; std::stable_sort(candidateFontFaces.begin(), candidateFontFaces.end(), compareFontFaces); unsigned numCandidates = candidateFontFaces.size(); for (unsigned i = 0; i < numCandidates; ++i) face->appendFontFace(candidateFontFaces[i]); } // We have a face. Ask it for a font data. If it cannot produce one, it will fail, and the OS will take over. return face->getFontData(fontDescription); }
static bool populateFontFaceWithArrayBuffer(CSSFontFace& fontFace, Ref<JSC::ArrayBufferView>&& arrayBufferView) { auto source = std::make_unique<CSSFontFaceSource>(fontFace, String(), nullptr, nullptr, WTFMove(arrayBufferView)); fontFace.adoptSource(WTFMove(source)); return false; }
static inline bool compareFontFaces(const CSSFontFace& first, const CSSFontFace& second) { FontTraitsMask firstTraitsMask = first.traitsMask(); FontTraitsMask secondTraitsMask = second.traitsMask(); bool firstHasDesiredVariant = firstTraitsMask & desiredTraitsMaskForComparison & FontVariantMask; bool secondHasDesiredVariant = secondTraitsMask & desiredTraitsMaskForComparison & FontVariantMask; if (firstHasDesiredVariant != secondHasDesiredVariant) return firstHasDesiredVariant; // We need to check font-variant css property for CSS2.1 compatibility. if ((desiredTraitsMaskForComparison & FontVariantSmallCapsMask) && !first.isLocalFallback() && !second.isLocalFallback()) { // Prefer a font that has indicated that it can only support small-caps to a font that claims to support // all variants. The specialized font is more likely to be true small-caps and not require synthesis. bool firstRequiresSmallCaps = (firstTraitsMask & FontVariantSmallCapsMask) && !(firstTraitsMask & FontVariantNormalMask); bool secondRequiresSmallCaps = (secondTraitsMask & FontVariantSmallCapsMask) && !(secondTraitsMask & FontVariantNormalMask); if (firstRequiresSmallCaps != secondRequiresSmallCaps) return firstRequiresSmallCaps; } bool firstHasDesiredStyle = firstTraitsMask & desiredTraitsMaskForComparison & FontStyleMask; bool secondHasDesiredStyle = secondTraitsMask & desiredTraitsMaskForComparison & FontStyleMask; if (firstHasDesiredStyle != secondHasDesiredStyle) return firstHasDesiredStyle; if ((desiredTraitsMaskForComparison & FontStyleItalicMask) && !first.isLocalFallback() && !second.isLocalFallback()) { // Prefer a font that has indicated that it can only support italics to a font that claims to support // all styles. The specialized font is more likely to be the one the author wants used. bool firstRequiresItalics = (firstTraitsMask & FontStyleItalicMask) && !(firstTraitsMask & FontStyleNormalMask); bool secondRequiresItalics = (secondTraitsMask & FontStyleItalicMask) && !(secondTraitsMask & FontStyleNormalMask); if (firstRequiresItalics != secondRequiresItalics) return firstRequiresItalics; } if (secondTraitsMask & desiredTraitsMaskForComparison & FontWeightMask) return false; if (firstTraitsMask & desiredTraitsMaskForComparison & FontWeightMask) return true; // http://www.w3.org/TR/2011/WD-css3-fonts-20111004/#font-matching-algorithm says : // - If the desired weight is less than 400, weights below the desired weight are checked in descending order followed by weights above the desired weight in ascending order until a match is found. // - If the desired weight is greater than 500, weights above the desired weight are checked in ascending order followed by weights below the desired weight in descending order until a match is found. // - If the desired weight is 400, 500 is checked first and then the rule for desired weights less than 400 is used. // - If the desired weight is 500, 400 is checked first and then the rule for desired weights less than 400 is used. static const unsigned fallbackRuleSets = 9; static const unsigned rulesPerSet = 8; static const FontTraitsMask weightFallbackRuleSets[fallbackRuleSets][rulesPerSet] = { { FontWeight200Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight100Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight200Mask, FontWeight100Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight500Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, { FontWeight700Mask, FontWeight800Mask, FontWeight900Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }, { FontWeight800Mask, FontWeight900Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }, { FontWeight900Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }, { FontWeight800Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask } }; unsigned ruleSetIndex = 0; unsigned w = FontWeight100Bit; while (!(desiredTraitsMaskForComparison & (1 << w))) { w++; ruleSetIndex++; } ASSERT_WITH_SECURITY_IMPLICATION(ruleSetIndex < fallbackRuleSets); const FontTraitsMask* weightFallbackRule = weightFallbackRuleSets[ruleSetIndex]; for (unsigned i = 0; i < rulesPerSet; ++i) { if (secondTraitsMask & weightFallbackRule[i]) return false; if (firstTraitsMask & weightFallbackRule[i]) return true; } return false; }
void CSSFontSelector::addFontFaceRule(const CSSFontFaceRuleImpl *fontFaceRule) { // Obtain the font-family property and the src property. Both must be defined. const CSSStyleDeclarationImpl *style = fontFaceRule->style(); CSSValueImpl *fontFamily = style->getPropertyCSSValue(CSS_PROP_FONT_FAMILY); CSSValueImpl *src = style->getPropertyCSSValue(CSS_PROP_SRC); CSSValueImpl *unicodeRange = style->getPropertyCSSValue(CSS_PROP_UNICODE_RANGE); if (!fontFamily || !src || !fontFamily->isValueList() || !src->isValueList() || (unicodeRange && !unicodeRange->isValueList())) { return; } CSSValueListImpl *familyList = static_cast<CSSValueListImpl *>(fontFamily); if (!familyList->length()) { return; } CSSValueListImpl *srcList = static_cast<CSSValueListImpl *>(src); if (!srcList->length()) { return; } // CSSValueListImpl* rangeList = static_cast<CSSValueListImpl*>(unicodeRange); unsigned traitsMask = 0; /* if (CSSValueImpl* fontStyle = style->getPropertyCSSValue(CSS_PROP_FONT_STYLE)) { if (fontStyle->isPrimitiveValue()) { CSSValueListImpl* list = new CSSValueListImpl(CSSValueListImpl::Comma); list->append(fontStyle); fontStyle = list; } else if (!fontStyle->isValueList()) return; CSSValueListImpl* styleList = static_cast<CSSValueListImpl*>(fontStyle); unsigned numStyles = styleList->length(); if (!numStyles) return; for (unsigned i = 0; i < numStyles; ++i) { switch (static_cast<CSSPrimitiveValueImpl*>(styleList[i])->getIdent()) { case CSS_ALL: traitsMask |= FontStyleMask; break; case CSS_NORMAL: traitsMask |= FontStyleNormalMask; break; case CSS_ITALIC: case CSS_OBLIQUE: traitsMask |= FontStyleItalicMask; break; default: break; } } } else traitsMask |= FontStyleMask; if (CSSValueImpl* fontWeight = style->getPropertyCSSValue(CSS_PROP_FONT_WEIGHT)) { if (fontWeight->isPrimitiveValue()) { CSSValueListImpl* list = new CSSValueListImpl(CSSValueListImpl::Comma); list->append(fontWeight); fontWeight = list; } else if (!fontWeight->isValueList()) return; CSSValueListImpl* weightList = static_cast<CSSValueListImpl*>(fontWeight); unsigned numWeights = weightList->length(); if (!numWeights) return; for (unsigned i = 0; i < numWeights; ++i) { switch (static_cast<CSSPrimitiveValueImpl*>(weightList[i])->getIdent()) { case CSS_VAL_ALL: traitsMask |= FontWeightMask; break; case CSS_VAL_BOLDER: case CSS_VAL_BOLD: case CSS_VAL_700: traitsMask |= FontWeight700Mask; break; case CSS_VAL_NORMAL: case CSS_VAL_400: traitsMask |= FontWeight400Mask; break; case CSS_VAL_900: traitsMask |= FontWeight900Mask; break; case CSS_VAL_800: traitsMask |= FontWeight800Mask; break; case CSS_VAL_600: traitsMask |= FontWeight600Mask; break; case CSS_VAL_500: traitsMask |= FontWeight500Mask; break; case CSS_VAL_300: traitsMask |= FontWeight300Mask; break; case CSS_VAL_LIGHTER: case CSS_VAL_200: traitsMask |= FontWeight200Mask; break; case CSS_VAL_100: traitsMask |= FontWeight100Mask; break; default: break; } } } else traitsMask |= FontWeightMask; if (CSSValueImpl* fontVariant = style->getPropertyCSSValue(CSS_PROP_FONT_VARIANT)) { if (fontVariant->isPrimitiveValue()) { CSSValueListImpl* list = new CSSValueListImpl(CSSValueListImpl::Comma); list->append(fontVariant); fontVariant = list; } else if (!fontVariant->isValueList()) return; CSSValueListImpl* variantList = static_cast<CSSValueListImpl*>(fontVariant); unsigned numVariants = variantList->length(); if (!numVariants) return; for (unsigned i = 0; i < numVariants; ++i) { switch (static_cast<CSSPrimitiveValueImpl*>(variantList[i])->getIdent()) { case CSS_VAL_ALL: traitsMask |= FontVariantMask; break; case CSS_VAL_NORMAL: traitsMask |= FontVariantNormalMask; break; case CSS_VAL_SMALL_CAPS: traitsMask |= FontVariantSmallCapsMask; break; default: break; } } } else traitsMask |= FontVariantNormalMask; */ // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace. CSSFontFace *fontFace = 0; const int srcLength = srcList->length(); #if 0 // ENABLE(SVG_FONTS) bool foundSVGFont = false; #endif for (int i = 0; i < srcLength; i++) { // An item in the list either specifies a string (local font name) or a URL (remote font to download). CSSFontFaceSrcValueImpl *item = static_cast<CSSFontFaceSrcValueImpl *>(srcList->item(i)); CSSFontFaceSource *source = 0; #if 0 // ENABLE(SVG_FONTS) foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement(); #endif if (!item->isLocal()) { if (item->isSupportedFormat() && m_document) { source = new CSSFontFaceSource(item->resource(), true /*distant*/); #if 0 // ENABLE(SVG_FONTS) if (foundSVGFont) { cachedFont->setSVGFont(true); } #endif } } else { source = new CSSFontFaceSource(item->resource()); } if (source) { #if 0 // ENABLE(SVG_FONTS) source->setSVGFontFaceElement(item->svgFontFaceElement()); #endif if (!fontFace) { fontFace = new CSSFontFace(static_cast<FontTraitsMask>(traitsMask), this); } fontFace->addSource(source); } } if (!fontFace || !fontFace->isValid()) { delete fontFace; return; } /* if (rangeList) { unsigned numRanges = rangeList->length(); for (unsigned i = 0; i < numRanges; i++) { CSSUnicodeRangeValueImpl* range = static_cast<CSSUnicodeRangeValueImpl*>(rangeList->item(i)); fontFace->addRange(range->from(), range->to()); } } */ // Hash under every single family name. int familyLength = familyList->length(); for (int i = 0; i < familyLength; i++) { CSSPrimitiveValueImpl *item = static_cast<CSSPrimitiveValueImpl *>(familyList->item(i)); DOMString familyName; if (item->primitiveType() == CSSPrimitiveValue::CSS_STRING) { familyName = DOMString(static_cast<FontFamilyValueImpl *>(item)->fontName()); } else if (item->primitiveType() == CSSPrimitiveValue::CSS_IDENT) { // We need to use the raw text for all the generic family types, since @font-face is a way of actually // defining what font to use for those types. switch (item->getIdent()) { case CSS_VAL_SERIF: familyName = "-khtml-serif"; break; case CSS_VAL_SANS_SERIF: familyName = "-khtml-sans-serif"; break; case CSS_VAL_CURSIVE: familyName = "-khtml-cursive"; break; case CSS_VAL_FANTASY: familyName = "-khtml-fantasy"; break; case CSS_VAL_MONOSPACE: familyName = "-khtml-monospace"; break; default: break; } } if (familyName.isEmpty()) { continue; } fontFace->addFamilyName(familyName); m_locallyInstalledFontFaces.insertMulti(familyName.lower(), fontFace); fontFace->ref(); #if 0 // ENABLE(SVG_FONTS) // SVG allows several <font> elements with the same font-family, differing only // in ie. font-variant. Be sure to pick up the right one - in getFontData below. if (foundSVGFont && (traitsMask & FontVariantSmallCapsMask)) { familyName += "-webkit-svg-small-caps"; } #endif /* Vector<RefPtr<CSSFontFace> >* familyFontFaces = m_fontFaces.get(familyName); if (!familyFontFaces) { familyFontFaces = new Vector<RefPtr<CSSFontFace> >; m_fontFaces.set(familyName, familyFontFaces); ASSERT(!m_locallyInstalledFontFaces.contains(familyName)); Vector<RefPtr<CSSFontFace> >* familyLocallyInstalledFaces; Vector<unsigned> locallyInstalledFontsTraitsMasks; fontCache()->getTraitsInFamily(familyName, locallyInstalledFontsTraitsMasks); unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsMasks.size(); if (numLocallyInstalledFaces) { familyLocallyInstalledFaces = new Vector<RefPtr<CSSFontFace> >; m_locallyInstalledFontFaces.set(familyName, familyLocallyInstalledFaces); for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) { RefPtr<CSSFontFace> locallyInstalledFontFace = CSSFontFace::create(static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i])); locallyInstalledFontFace->addSource(new CSSFontFaceSource(familyName)); ASSERT(locallyInstalledFontFace->isValid()); familyLocallyInstalledFaces->append(locallyInstalledFontFace); } } } familyFontFaces->append(fontFace); */ } // Should be impossible, but in case empty/invalid family name makes it through... if (fontFace->refCount() < 1) { delete fontFace; } }