⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 276295 in webkit


Ignore:
Timestamp:
Apr 20, 2021, 2:50:24 AM (5 years ago)
Author:
Chris Lord
Message:

Don't use the full CSS parser for CSSFontFaceSet
https://bugs.webkit.org/show_bug.cgi?id=224749

Reviewed by Darin Adler.

Replace use of the full CSS parser in CSSFontFaceSet with
CSSPropertyParserWorkerSafe::parseFont to parse font shorthands. This
makes CSSFontFaceSet safe to use in a Worker (required for
OffscreenCanvas) and ought also to be faster, at the cost of a slight
increase in lines of code.

No new tests, covered by existing tests.

  • css/CSSFontFaceSet.cpp:

(WebCore::computeFontSelectionRequest):
(WebCore::CSSFontFaceSet::matchingFacesExcludingPreinstalledFonts):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r276293 r276295  
     12021-04-20  Chris Lord  <clord@igalia.com>
     2
     3        Don't use the full CSS parser for CSSFontFaceSet
     4        https://bugs.webkit.org/show_bug.cgi?id=224749
     5
     6        Reviewed by Darin Adler.
     7
     8        Replace use of the full CSS parser in CSSFontFaceSet with
     9        CSSPropertyParserWorkerSafe::parseFont to parse font shorthands. This
     10        makes CSSFontFaceSet safe to use in a Worker (required for
     11        OffscreenCanvas) and ought also to be faster, at the cost of a slight
     12        increase in lines of code.
     13
     14        No new tests, covered by existing tests.
     15
     16        * css/CSSFontFaceSet.cpp:
     17        (WebCore::computeFontSelectionRequest):
     18        (WebCore::CSSFontFaceSet::matchingFacesExcludingPreinstalledFonts):
     19
    1202021-04-20  Tim Nguyen  <ntim@apple.com>
    221
  • trunk/Source/WebCore/css/CSSFontFaceSet.cpp

    r276015 r276295  
    3333#include "CSSParser.h"
    3434#include "CSSPrimitiveValue.h"
     35#include "CSSPropertyParserHelpers.h"
     36#include "CSSPropertyParserWorkerSafe.h"
    3537#include "CSSSegmentedFontFace.h"
    3638#include "CSSValueList.h"
     
    307309}
    308310
    309 static ExceptionOr<FontSelectionRequest> computeFontSelectionRequest(MutableStyleProperties& style)
    310 {
    311     RefPtr<CSSValue> weightValue = style.getPropertyCSSValue(CSSPropertyFontWeight).get();
    312     if (!weightValue || weightValue->isInitialValue())
    313         weightValue = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal).ptr();
    314 
    315     RefPtr<CSSValue> stretchValue = style.getPropertyCSSValue(CSSPropertyFontStretch).get();
    316     if (!stretchValue || stretchValue->isInitialValue())
    317         stretchValue = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal).ptr();
    318 
    319     RefPtr<CSSValue> styleValue = style.getPropertyCSSValue(CSSPropertyFontStyle).get();
    320     if (!styleValue || styleValue->isInitialValue())
    321         styleValue = CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueNormal));
    322 
    323     if (weightValue->isGlobalKeyword() || stretchValue->isGlobalKeyword() || styleValue->isGlobalKeyword())
    324         return Exception { SyntaxError };
    325 
    326     auto weightSelectionValue = Style::BuilderConverter::convertFontWeightFromValue(*weightValue);
    327     auto stretchSelectionValue = Style::BuilderConverter::convertFontStretchFromValue(*stretchValue);
    328     auto styleSelectionValue = Style::BuilderConverter::convertFontStyleFromValue(*styleValue);
    329 
    330     return {{ weightSelectionValue, stretchSelectionValue, styleSelectionValue }};
     311static FontSelectionRequest computeFontSelectionRequest(CSSPropertyParserHelpers::FontRaw& font)
     312{
     313    auto weightSelectionValue = font.weight
     314        ? WTF::switchOn(*font.weight, [&] (CSSValueID keyword) {
     315            switch (keyword) {
     316            case CSSValueNormal:
     317                return normalWeightValue();
     318            case CSSValueBold:
     319            case CSSValueBolder:
     320                return boldWeightValue();
     321            case CSSValueLighter:
     322                return lightWeightValue();
     323            default:
     324                ASSERT_NOT_REACHED();
     325                return normalWeightValue();
     326            }
     327        }, [&] (double weight) {
     328            return FontSelectionValue::clampFloat(weight);
     329        }) : normalWeightValue();
     330
     331    // Because this is a FontRaw, we know we should be able to dereference stretchSelectionValue as
     332    // consumeFontStretchKeywordValueRaw only returns results valid to pass to fontStretchValue.
     333    auto stretchSelectionValue = fontStretchValue(font.stretch.valueOr(CSSValueNormal));
     334    ASSERT(stretchSelectionValue);
     335
     336    auto styleKeyword = font.style ? font.style->style : CSSValueNormal;
     337    auto styleSelectionValue = [&] () -> Optional<FontSelectionValue> {
     338        if (styleKeyword == CSSValueNormal)
     339            return WTF::nullopt;
     340        if (styleKeyword == CSSValueItalic)
     341            return italicValue();
     342        ASSERT(font.style && styleKeyword == CSSValueOblique);
     343        float degrees = 0;
     344        if (font.style->angle)
     345            degrees = static_cast<float>(CSSPrimitiveValue::computeDegrees(font.style->angle->type, font.style->angle->value));
     346        return FontSelectionValue(degrees);
     347    }();
     348
     349    return { weightSelectionValue, *stretchSelectionValue, styleSelectionValue };
    331350}
    332351
     
    348367}
    349368
    350 ExceptionOr<Vector<std::reference_wrapper<CSSFontFace>>> CSSFontFaceSet::matchingFacesExcludingPreinstalledFonts(const String& font, const String& string)
    351 {
    352     auto style = MutableStyleProperties::create();
    353     auto parseResult = CSSParser::parseValue(style, CSSPropertyFont, font, true, HTMLStandardMode);
    354     if (parseResult == CSSParser::ParseResult::Error)
     369ExceptionOr<Vector<std::reference_wrapper<CSSFontFace>>> CSSFontFaceSet::matchingFacesExcludingPreinstalledFonts(const String& fontShorthand, const String& string)
     370{
     371    auto font = CSSPropertyParserWorkerSafe::parseFont(fontShorthand, HTMLStandardMode);
     372    if (!font)
    355373        return Exception { SyntaxError };
    356 
    357     auto requestOrException = computeFontSelectionRequest(style.get());
    358     if (requestOrException.hasException())
    359         return requestOrException.releaseException();
    360     auto request = requestOrException.releaseReturnValue();
    361 
    362     auto family = style->getPropertyCSSValue(CSSPropertyFontFamily);
    363     if (!is<CSSValueList>(family))
    364         return Exception { SyntaxError };
    365     CSSValueList& familyList = downcast<CSSValueList>(*family);
    366374
    367375    HashSet<AtomString> uniqueFamilies;
    368376    Vector<AtomString> familyOrder;
    369     for (auto& family : familyList) {
    370         auto& primitive = downcast<CSSPrimitiveValue>(family.get());
    371         if (!primitive.isFontFamily())
    372             continue;
    373         if (uniqueFamilies.add(primitive.fontFamily().familyName).isNewEntry)
    374             familyOrder.append(primitive.fontFamily().familyName);
     377    for (auto& familyRaw : font->family) {
     378        AtomString familyAtom;
     379        WTF::switchOn(familyRaw, [&] (CSSValueID ident) {
     380            if (ident != CSSValueWebkitBody)
     381                familyAtom = familyNamesData->at(CSSPropertyParserHelpers::genericFontFamilyIndex(ident));
     382            else {
     383                ASSERT(m_owningFontSelector && m_owningFontSelector->scriptExecutionContext());
     384                familyAtom = m_owningFontSelector->scriptExecutionContext()->settingsValues().fontGenericFamilies.standardFontFamily();
     385            }
     386        }, [&] (const String& familyString) {
     387            familyAtom = familyString;
     388        });
     389
     390        if (!familyAtom.isEmpty() && uniqueFamilies.add(familyAtom).isNewEntry)
     391            familyOrder.append(familyAtom);
    375392    }
    376393
    377394    HashSet<CSSFontFace*> resultConstituents;
     395    auto request = computeFontSelectionRequest(*font);
    378396    for (auto codePoint : codePointsFromString(string)) {
    379397        bool found = false;
Note: See TracChangeset for help on using the changeset viewer.