source: webkit/trunk/Source/WebCore/css/FontFace.cpp

Last change on this file was 293285, checked in by Chris Dumez, 3 years ago

Move global AtomStrings to a common header to promote reuse
https://bugs.webkit.org/show_bug.cgi?id=239585

Reviewed by Geoff Garen and Darin Adler.

Source/WebCore:

  • Headers.cmake:
  • Modules/async-clipboard/Clipboard.cpp:

(WebCore::Clipboard::getType):

  • Modules/mediastream/MediaStreamTrack.cpp:

(WebCore::MediaStreamTrack::contentHint const):
(WebCore::MediaStreamTrack::setContentHint):

  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • animation/AnimationEffect.cpp:

(WebCore::AnimationEffect::getTiming const):
(WebCore::AnimationEffect::updateTiming):

  • animation/EffectTiming.h:
  • contentextensions/ContentExtensionParser.cpp:

(WebCore::ContentExtensions::isValidCSSSelector):

  • css/CSSStyleSheet.h:
  • css/FontFace.cpp:

(WebCore::FontFace::display const):

  • css/MediaFeatureNames.cpp:

(WebCore::MediaFeatureNames::init):

  • dom/DataTransfer.cpp:

(WebCore::normalizeType):
(WebCore::DataTransfer::setDataFromItemList):
(WebCore::DataTransfer::createForInputEvent):
(WebCore::DataTransfer::dropEffect const):

  • dom/Document.cpp:

(WebCore::Document::designMode const):

  • dom/InlineStyleSheetOwner.cpp:

(WebCore::isValidCSSContentType):

  • dom/ProcessingInstruction.cpp:

(WebCore::ProcessingInstruction::checkStyleSheet):

  • dom/mac/ImageControlsMac.cpp:
  • editing/FontShadow.cpp:

(WebCore::serializationForCSS):

  • editing/ReplaceSelectionCommand.cpp:

(WebCore::ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline):

  • editing/cocoa/DataDetection.mm:
  • editing/cocoa/HTMLConverter.mm:

(HTMLConverterCaches::propertyValueForNode):
(HTMLConverter::computedAttributesForElement):
(HTMLConverter::_enterElement):
(HTMLConverter::_processElement):

  • editing/markup.cpp:

(WebCore::createFragmentForTransformToFragment):

  • html/Autocapitalize.cpp:

(WebCore::stringForAutocapitalizeType):

  • html/Autofill.cpp:

(WebCore::AutofillData::createFromHTMLFormControlElement):

  • html/BaseCheckableInputType.cpp:

(WebCore::BaseCheckableInputType::saveFormControlState const):
(WebCore::BaseCheckableInputType::restoreFormControlState):
(WebCore::BaseCheckableInputType::fallbackValue const):

  • html/EnterKeyHint.cpp:

(WebCore::attributeValueForEnterKeyHint):

  • html/HTMLAudioElement.cpp:

(WebCore::HTMLAudioElement::createForLegacyFactoryFunction):

  • html/HTMLButtonElement.cpp:

(WebCore::HTMLButtonElement::formControlType const):

  • html/HTMLElement.cpp:

(WebCore::toValidDirValue):
(WebCore::HTMLElement::contentEditable const):
(WebCore::HTMLElement::setContentEditable):
(WebCore::HTMLElement::setAutocorrect):
(WebCore::plaintextOnlyName): Deleted.

  • html/HTMLFormElement.cpp:

(WebCore::HTMLFormElement::autocomplete const):

  • html/HTMLIFrameElement.cpp:

(WebCore::HTMLIFrameElement::loadingForBindings const):

  • html/HTMLImageElement.cpp:

(WebCore::HTMLImageElement::decoding const):
(WebCore::HTMLImageElement::loadingForBindings const):

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::preload const):

  • html/HTMLTextFormControlElement.cpp:

(WebCore::directionString):

  • html/InputMode.cpp:

(WebCore::InputModeNames::none):
(WebCore::InputModeNames::text):
(WebCore::InputModeNames::tel):
(WebCore::InputModeNames::url):
(WebCore::InputModeNames::email):
(WebCore::InputModeNames::search):

  • html/InputTypeNames.cpp:

(WebCore::InputTypeNames::email):
(WebCore::InputTypeNames::reset):
(WebCore::InputTypeNames::search):
(WebCore::InputTypeNames::submit):
(WebCore::InputTypeNames::telephone):
(WebCore::InputTypeNames::text):
(WebCore::InputTypeNames::url):

  • html/shadow/TextControlInnerElements.cpp:

(WebCore::TextControlInnerTextElement::updateInnerTextElementEditabilityImpl):

  • html/track/AudioTrack.cpp:

(WebCore::AudioTrack::isValidKind const):
(WebCore::AudioTrack::updateKindFromPrivate):
(WebCore::AudioTrack::alternativeKeyword): Deleted.
(WebCore::AudioTrack::mainKeyword): Deleted.
(WebCore::AudioTrack::commentaryKeyword): Deleted.

  • html/track/AudioTrack.h:
  • html/track/TextTrack.cpp:

(WebCore::TextTrack::TextTrack):
(WebCore::TextTrack::isValidKindKeyword):
(WebCore::TextTrack::kindKeyword const):
(WebCore::TextTrack::subtitlesKeyword): Deleted.
(WebCore::captionsKeyword): Deleted.

  • html/track/TextTrack.h:
  • html/track/VTTCue.cpp:

(WebCore::VTTCue::positionAlign const):
(WebCore::VTTCue::setPositionAlign):
(WebCore::VTTCue::toJSON const):
(WebCore::autoKeyword): Deleted.

  • html/track/VideoTrack.cpp:

(WebCore::VideoTrack::isValidKind const):
(WebCore::VideoTrack::updateKindFromPrivate):
(WebCore::VideoTrack::alternativeKeyword): Deleted.
(WebCore::VideoTrack::captionsKeyword): Deleted.
(WebCore::VideoTrack::mainKeyword): Deleted.
(WebCore::VideoTrack::subtitlesKeyword): Deleted.
(WebCore::VideoTrack::commentaryKeyword): Deleted.

  • html/track/VideoTrack.h:
  • html/track/WebVTTParser.cpp:

(WebCore::WebVTTParser::WebVTTParser):

  • inspector/agents/InspectorCSSAgent.cpp:

(WebCore::InspectorCSSAgent::createInspectorStyleSheetForDocument):

  • loader/FormSubmission.cpp:

(WebCore::FormSubmission::Attributes::parseEncodingType):

  • loader/NavigationScheduler.cpp:
  • loader/TextResourceDecoder.cpp:

(WebCore::TextResourceDecoder::textFromUTF8):

  • loader/archive/mhtml/MHTMLParser.cpp:

(WebCore::MHTMLParser::addResourceToArchive):

  • loader/cache/CachedCSSStyleSheet.cpp:

(WebCore::CachedCSSStyleSheet::CachedCSSStyleSheet):

  • mathml/MathMLPresentationElement.cpp:
  • page/CaptionUserPreferencesMediaAF.cpp:

(WebCore::addAudioTrackKindDisplayNameIfNeeded):

  • page/EventSource.cpp:

(WebCore::EventSource::EventSource):

  • page/Page.cpp:

(WebCore::Page::userStyleSheet const):

  • page/PageSerializer.cpp:

(WebCore::PageSerializer::serializeCSSStyleSheet):

  • page/PrintContext.cpp:

(WebCore::PrintContext::pageProperty):

  • page/ProcessWarming.cpp:

(WebCore::ProcessWarming::initializeNames):

  • platform/CommonAtomStrings.cpp: Added.

(WebCore::initializeCommonAtomStrings):

  • platform/CommonAtomStrings.h: Added.

(WebCore::alternativeAtom):
(WebCore::autoAtom):
(WebCore::captionsAtom):
(WebCore::commentaryAtom):
(WebCore::cssContentTypeAtom):
(WebCore::eagerAtom):
(WebCore::emailAtom):
(WebCore::falseAtom):
(WebCore::lazyAtom):
(WebCore::mainAtom):
(WebCore::noneAtom):
(WebCore::offAtom):
(WebCore::onAtom):
(WebCore::plaintextOnlyAtom):
(WebCore::resetAtom):
(WebCore::searchAtom):
(WebCore::submitAtom):
(WebCore::subtitlesAtom):
(WebCore::telAtom):
(WebCore::textAtom):
(WebCore::textPlainContentTypeAtom):
(WebCore::trueAtom):
(WebCore::urlAtom):

  • platform/Pasteboard.cpp:

(WebCore::Pasteboard::isSafeTypeForDOMToReadAndWrite):

  • platform/StaticPasteboard.cpp:

(WebCore::StaticPasteboard::writePlainText):

  • platform/animation/Animation.cpp:

(WebCore::Animation::initialName const):

  • platform/graphics/MediaPlayer.cpp:

(WebCore::MediaPlayer::load):
(WebCore::textPlain): Deleted.

  • platform/ios/wak/WebCoreThread.mm:

(StartWebThread):

  • platform/network/HTTPParsers.cpp:
  • platform/network/ios/WebCoreURLResponseIOS.h:

(WebCore::shouldUseQuickLookForMIMEType):

  • style/Styleable.cpp:

(WebCore::Styleable::animationListContainsNewlyValidAnimation const):
(WebCore::Styleable::updateCSSAnimations const):

  • svg/SVGAnimateMotionElement.cpp:

(WebCore::SVGAnimateMotionElement::rotateMode const):

  • svg/SVGAnimationElement.cpp:

(WebCore::sumAtom):
(WebCore::SVGAnimationElement::isAdditive const):
(WebCore::SVGAnimationElement::isAccumulated const):

  • svg/SVGFEConvolveMatrixElement.cpp:
  • svg/SVGFEConvolveMatrixElement.h:

(WebCore::SVGPropertyTraits<EdgeModeType>::toString):
(WebCore::SVGPropertyTraits<EdgeModeType>::fromString):

  • svg/SVGMarkerTypes.h:

(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::fromString):
(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::toString):
(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::autoString): Deleted.

  • svg/SVGStyleElement.cpp:

(WebCore::SVGStyleElement::type const):

  • svg/SVGTextPathElement.h:

(WebCore::SVGPropertyTraits<SVGTextPathSpacingType>::toString):
(WebCore::SVGPropertyTraits<SVGTextPathSpacingType>::fromString):

  • svg/animation/SVGSMILElement.cpp:

(WebCore::indefiniteAtom):
(WebCore::SVGSMILElement::parseClockValue):
(WebCore::SVGSMILElement::repeatCount const):

  • svg/properties/SVGPropertyTraits.h:
  • workers/service/context/ServiceWorkerThread.cpp:

(WebCore::m_notificationClient):

  • xml/XPathValue.cpp:

Source/WebKit:

  • GPUProcess/GPUProcess.cpp:

(WebKit::GPUProcess::initializeGPUProcess):

  • NetworkProcess/NetworkProcess.cpp:

(WebKit::NetworkProcess::initializeNetworkProcess):

  • Shared/Cocoa/WebKit2InitializeCocoa.mm:

(WebKit::runInitializationCode):

  • Shared/WebKit2Initialize.cpp:

(WebKit::InitializeWebKit2):

  • UIProcess/API/APIContentRuleListStore.cpp:

(API::ContentRuleListStore::compileContentRuleList):

Source/WebKitLegacy/win:

  • WebKitGraphics.cpp:

(makeFont):

Source/WTF:

  • wtf/text/AtomString.cpp:

(WTF::AtomString::init):

  • wtf/text/AtomString.h:

(WTF::xmlnsAtom):
(WTF::trueAtom): Deleted.
(WTF::falseAtom): Deleted.

Tools:

  • TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:

(TestWebKitAPI::makeBackend):

File size: 17.6 KB
Line 
1/*
2 * Copyright (C) 2016 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "FontFace.h"
28
29#include "CSSComputedStyleDeclaration.h"
30#include "CSSFontFaceSource.h"
31#include "CSSFontFeatureValue.h"
32#include "CSSFontSelector.h"
33#include "CSSFontStyleValue.h"
34#include "CSSParser.h"
35#include "CSSPrimitiveValueMappings.h"
36#include "CSSPropertyParserWorkerSafe.h"
37#include "CSSUnicodeRangeValue.h"
38#include "CSSValueList.h"
39#include "CSSValuePool.h"
40#include "DOMPromiseProxy.h"
41#include "Document.h"
42#include "JSFontFace.h"
43#include "Quirks.h"
44#include "StyleProperties.h"
45#include <JavaScriptCore/ArrayBuffer.h>
46#include <JavaScriptCore/ArrayBufferView.h>
47#include <JavaScriptCore/JSCInlines.h>
48#include <wtf/text/StringBuilder.h>
49
50namespace WebCore {
51
52static bool populateFontFaceWithArrayBuffer(CSSFontFace& fontFace, Ref<JSC::ArrayBufferView>&& arrayBufferView)
53{
54 auto source = makeUnique<CSSFontFaceSource>(fontFace, String(), WTFMove(arrayBufferView));
55 fontFace.adoptSource(WTFMove(source));
56 return false;
57}
58
59void FontFace::setErrorState()
60{
61 m_loadedPromise->reject(Exception { SyntaxError });
62 m_backing->setErrorState();
63}
64
65Ref<FontFace> FontFace::create(ScriptExecutionContext& context, const String& family, Source&& source, const Descriptors& descriptors)
66{
67 ASSERT(context.cssFontSelector());
68 auto result = adoptRef(*new FontFace(*context.cssFontSelector()));
69 result->suspendIfNeeded();
70
71 bool dataRequiresAsynchronousLoading = true;
72
73 auto setFamilyResult = result->setFamily(context, family);
74 if (setFamilyResult.hasException()) {
75 result->setErrorState();
76 return result;
77 }
78
79 auto sourceConversionResult = WTF::switchOn(source,
80 [&] (String& string) -> ExceptionOr<void> {
81 auto value = CSSPropertyParserWorkerSafe::parseFontFaceSrc(string, is<Document>(context) ? CSSParserContext(downcast<Document>(context)) : HTMLStandardMode);
82 if (!value)
83 return Exception { SyntaxError };
84 CSSFontFace::appendSources(result->backing(), *value, &context, false);
85 return { };
86 },
87 [&] (RefPtr<ArrayBufferView>& arrayBufferView) -> ExceptionOr<void> {
88 dataRequiresAsynchronousLoading = populateFontFaceWithArrayBuffer(result->backing(), arrayBufferView.releaseNonNull());
89 return { };
90 },
91 [&] (RefPtr<ArrayBuffer>& arrayBuffer) -> ExceptionOr<void> {
92 unsigned byteLength = arrayBuffer->byteLength();
93 auto arrayBufferView = JSC::Uint8Array::create(WTFMove(arrayBuffer), 0, byteLength);
94 dataRequiresAsynchronousLoading = populateFontFaceWithArrayBuffer(result->backing(), WTFMove(arrayBufferView));
95 return { };
96 }
97 );
98
99 if (sourceConversionResult.hasException()) {
100 result->setErrorState();
101 return result;
102 }
103
104 // These ternaries match the default strings inside the FontFaceDescriptors dictionary inside FontFace.idl.
105 auto setStyleResult = result->setStyle(context, descriptors.style.isEmpty() ? "normal"_s : descriptors.style);
106 if (setStyleResult.hasException()) {
107 result->setErrorState();
108 return result;
109 }
110 auto setWeightResult = result->setWeight(context, descriptors.weight.isEmpty() ? "normal"_s : descriptors.weight);
111 if (setWeightResult.hasException()) {
112 result->setErrorState();
113 return result;
114 }
115 auto setStretchResult = result->setStretch(context, descriptors.stretch.isEmpty() ? "normal"_s : descriptors.stretch);
116 if (setStretchResult.hasException()) {
117 result->setErrorState();
118 return result;
119 }
120 auto setUnicodeRangeResult = result->setUnicodeRange(context, descriptors.unicodeRange.isEmpty() ? "U+0-10FFFF"_s : descriptors.unicodeRange);
121 if (setUnicodeRangeResult.hasException()) {
122 result->setErrorState();
123 return result;
124 }
125 auto setFeatureSettingsResult = result->setFeatureSettings(context, descriptors.featureSettings.isEmpty() ? "normal"_s : descriptors.featureSettings);
126 if (setFeatureSettingsResult.hasException()) {
127 result->setErrorState();
128 return result;
129 }
130 auto setDisplayResult = result->setDisplay(context, descriptors.display.isEmpty() ? "auto"_s : descriptors.display);
131 if (setDisplayResult.hasException()) {
132 result->setErrorState();
133 return result;
134 }
135
136 if (!dataRequiresAsynchronousLoading) {
137 result->backing().load();
138 auto status = result->backing().status();
139 ASSERT_UNUSED(status, status == CSSFontFace::Status::Success || status == CSSFontFace::Status::Failure);
140 }
141
142 return result;
143}
144
145Ref<FontFace> FontFace::create(ScriptExecutionContext* context, CSSFontFace& face)
146{
147 auto fontFace = adoptRef(*new FontFace(context, face));
148 fontFace->suspendIfNeeded();
149 return fontFace;
150}
151
152FontFace::FontFace(CSSFontSelector& fontSelector)
153 : ActiveDOMObject(fontSelector.scriptExecutionContext())
154 , m_backing(CSSFontFace::create(fontSelector, nullptr, this))
155 , m_loadedPromise(makeUniqueRef<LoadedPromise>(*this, &FontFace::loadedPromiseResolve))
156{
157 m_backing->addClient(*this);
158}
159
160FontFace::FontFace(ScriptExecutionContext* context, CSSFontFace& face)
161 : ActiveDOMObject(context)
162 , m_backing(face)
163 , m_loadedPromise(makeUniqueRef<LoadedPromise>(*this, &FontFace::loadedPromiseResolve))
164{
165 m_backing->addClient(*this);
166}
167
168FontFace::~FontFace()
169{
170 m_backing->removeClient(*this);
171}
172
173ExceptionOr<void> FontFace::setFamily(ScriptExecutionContext& context, const String& family)
174{
175 if (family.isEmpty())
176 return Exception { SyntaxError };
177
178 String familyNameToUse = family;
179 // FIXME: Quirks currently aren't present on Workers, but should likely be inherited
180 // from the parent Document where applicable.
181 if (familyNameToUse.contains('\'') && is<Document>(context) && downcast<Document>(context).quirks().shouldStripQuotationMarkInFontFaceSetFamily())
182 familyNameToUse = family.removeCharacters([](auto character) { return character == '\''; });
183
184 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=196381 Don't use a list here.
185 // See consumeFontFamilyDescriptor() in CSSPropertyParser.cpp for why we're using it.
186 auto list = CSSValueList::createCommaSeparated();
187 list->append(context.cssValuePool().createFontFamilyValue(familyNameToUse));
188 bool success = m_backing->setFamilies(list);
189 if (!success)
190 return Exception { SyntaxError };
191 return { };
192}
193
194ExceptionOr<void> FontFace::setStyle(ScriptExecutionContext& context, const String& style)
195{
196 if (style.isEmpty())
197 return Exception { SyntaxError };
198
199 if (auto value = CSSPropertyParserWorkerSafe::parseFontFaceStyle(style, context)) {
200 m_backing->setStyle(*value);
201 return { };
202 }
203 return Exception { SyntaxError };
204}
205
206ExceptionOr<void> FontFace::setWeight(ScriptExecutionContext& context, const String& weight)
207{
208 if (weight.isEmpty())
209 return Exception { SyntaxError };
210
211 if (auto value = CSSPropertyParserWorkerSafe::parseFontFaceWeight(weight, context)) {
212 m_backing->setWeight(*value);
213 return { };
214 }
215 return Exception { SyntaxError };
216}
217
218ExceptionOr<void> FontFace::setStretch(ScriptExecutionContext& context, const String& stretch)
219{
220 if (stretch.isEmpty())
221 return Exception { SyntaxError };
222
223 if (auto value = CSSPropertyParserWorkerSafe::parseFontFaceStretch(stretch, context)) {
224 m_backing->setStretch(*value);
225 return { };
226 }
227 return Exception { SyntaxError };
228}
229
230ExceptionOr<void> FontFace::setUnicodeRange(ScriptExecutionContext& context, const String& unicodeRange)
231{
232 if (unicodeRange.isEmpty())
233 return Exception { SyntaxError };
234
235 bool success = false;
236 if (auto value = CSSPropertyParserWorkerSafe::parseFontFaceUnicodeRange(unicodeRange, context))
237 success = m_backing->setUnicodeRange(*value);
238 if (!success)
239 return Exception { SyntaxError };
240 return { };
241}
242
243ExceptionOr<void> FontFace::setFeatureSettings(ScriptExecutionContext& context, const String& featureSettings)
244{
245 if (featureSettings.isEmpty())
246 return Exception { SyntaxError };
247
248 auto value = CSSPropertyParserWorkerSafe::parseFontFaceFeatureSettings(featureSettings, context);
249 if (!value)
250 return Exception { SyntaxError };
251 m_backing->setFeatureSettings(*value);
252 return { };
253}
254
255ExceptionOr<void> FontFace::setDisplay(ScriptExecutionContext& context, const String& display)
256{
257 if (display.isEmpty())
258 return Exception { SyntaxError };
259
260 if (auto value = CSSPropertyParserWorkerSafe::parseFontFaceDisplay(display, context)) {
261 m_backing->setLoadingBehavior(*value);
262 return { };
263 }
264
265 return Exception { SyntaxError };
266}
267
268String FontFace::family() const
269{
270 m_backing->updateStyleIfNeeded();
271
272 const auto& families = m_backing->families();
273 if (!families)
274 return "normal"_s;
275 auto familiesUnrwapped = families.value();
276 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=196381 This is only here because CSSFontFace erroneously uses a list of values instead of a single value.
277 // See consumeFontFamilyDescriptor() in CSSPropertyParser.cpp.
278 if (familiesUnrwapped->length() == 1) {
279 if (familiesUnrwapped->item(0)) {
280 auto& item = *familiesUnrwapped->item(0);
281 if (item.isPrimitiveValue()) {
282 auto& primitiveValue = downcast<CSSPrimitiveValue>(item);
283 if (primitiveValue.isFontFamily()) {
284 auto& fontFamily = primitiveValue.fontFamily();
285 return fontFamily.familyName;
286 }
287 }
288 }
289 }
290 return familiesUnrwapped->cssText();
291}
292
293String FontFace::style() const
294{
295 m_backing->updateStyleIfNeeded();
296 const auto& styleWrapped = m_backing->italic();
297
298 if (!styleWrapped)
299 return "normal"_s;
300 auto style = styleWrapped.value();
301 auto minimum = ComputedStyleExtractor::fontStyleFromStyleValue(style.minimum, FontStyleAxis::ital);
302 auto maximum = ComputedStyleExtractor::fontStyleFromStyleValue(style.maximum, FontStyleAxis::ital);
303
304 if (minimum.get().equals(maximum.get()))
305 return minimum->cssText();
306
307 auto minimumNonKeyword = ComputedStyleExtractor::fontNonKeywordStyleFromStyleValue(style.minimum);
308 auto maximumNonKeyword = ComputedStyleExtractor::fontNonKeywordStyleFromStyleValue(style.maximum);
309
310 ASSERT(minimumNonKeyword->fontStyleValue->valueID() == CSSValueOblique);
311 ASSERT(maximumNonKeyword->fontStyleValue->valueID() == CSSValueOblique);
312
313 StringBuilder builder;
314 builder.append(minimumNonKeyword->fontStyleValue->cssText());
315 builder.append(' ');
316 if (minimum->obliqueValue.get() == maximum->obliqueValue.get())
317 builder.append(minimumNonKeyword->obliqueValue->cssText());
318 else {
319 builder.append(minimumNonKeyword->obliqueValue->cssText());
320 builder.append(' ');
321 builder.append(maximumNonKeyword->obliqueValue->cssText());
322 }
323 return builder.toString();
324
325}
326
327String FontFace::weight() const
328{
329 m_backing->updateStyleIfNeeded();
330 const auto& weightWrapped = m_backing->weight();
331 if (!weightWrapped)
332 return "normal"_s;
333 auto weight = weightWrapped.value();
334 auto minimum = ComputedStyleExtractor::fontWeightFromStyleValue(weight.minimum);
335 auto maximum = ComputedStyleExtractor::fontWeightFromStyleValue(weight.maximum);
336
337 if (minimum.get().equals(maximum.get()))
338 return minimum->cssText();
339
340 auto minimumNonKeyword = ComputedStyleExtractor::fontNonKeywordWeightFromStyleValue(weight.minimum);
341 auto maximumNonKeyword = ComputedStyleExtractor::fontNonKeywordWeightFromStyleValue(weight.maximum);
342
343 StringBuilder builder;
344 builder.append(minimumNonKeyword->cssText());
345 builder.append(' ');
346 builder.append(maximumNonKeyword->cssText());
347 return builder.toString();
348}
349
350String FontFace::stretch() const
351{
352 m_backing->updateStyleIfNeeded();
353 const auto& stretchWrapped = m_backing->stretch();
354 if (!stretchWrapped)
355 return "normal"_s;
356 auto stretch = stretchWrapped.value();
357 auto minimum = ComputedStyleExtractor::fontStretchFromStyleValue(stretch.minimum);
358 auto maximum = ComputedStyleExtractor::fontStretchFromStyleValue(stretch.maximum);
359
360 if (minimum.get().equals(maximum.get()))
361 return minimum->cssText();
362
363 auto minimumNonKeyword = ComputedStyleExtractor::fontNonKeywordStretchFromStyleValue(stretch.minimum);
364 auto maximumNonKeyword = ComputedStyleExtractor::fontNonKeywordStretchFromStyleValue(stretch.maximum);
365
366 StringBuilder builder;
367 builder.append(minimumNonKeyword->cssText());
368 builder.append(' ');
369 builder.append(maximumNonKeyword->cssText());
370 return builder.toString();
371}
372
373String FontFace::unicodeRange() const
374{
375 m_backing->updateStyleIfNeeded();
376 const auto& rangesWrapped = m_backing->ranges();
377 if (!rangesWrapped)
378 return "U+0-10FFFF"_s;
379 auto ranges = rangesWrapped.value();
380 if (!ranges.size())
381 return "U+0-10FFFF"_s;
382 auto values = CSSValueList::createCommaSeparated();
383 for (auto& range : ranges)
384 values->append(CSSUnicodeRangeValue::create(range.from, range.to));
385 return values->cssText();
386}
387
388String FontFace::featureSettings() const
389{
390 m_backing->updateStyleIfNeeded();
391 const auto& featureSettingsWrapped = m_backing->featureSettings();
392 if (!featureSettingsWrapped)
393 return "normal"_s;
394 auto featureSettings = featureSettingsWrapped.value();
395 if (!featureSettings.size())
396 return "normal"_s;
397 auto list = CSSValueList::createCommaSeparated();
398 for (auto& feature : featureSettings)
399 list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value()));
400 return list->cssText();
401}
402
403String FontFace::display(ScriptExecutionContext& context) const
404{
405 m_backing->updateStyleIfNeeded();
406 const auto& loadingBehaviorWrapped = m_backing->loadingBehavior();
407 if (!loadingBehaviorWrapped)
408 return autoAtom();
409 return context.cssValuePool().createValue(loadingBehaviorWrapped.value())->cssText();
410}
411
412auto FontFace::status() const -> LoadStatus
413{
414 switch (m_backing->status()) {
415 case CSSFontFace::Status::Pending:
416 return LoadStatus::Unloaded;
417 case CSSFontFace::Status::Loading:
418 return LoadStatus::Loading;
419 case CSSFontFace::Status::TimedOut:
420 return LoadStatus::Error;
421 case CSSFontFace::Status::Success:
422 return LoadStatus::Loaded;
423 case CSSFontFace::Status::Failure:
424 return LoadStatus::Error;
425 }
426 ASSERT_NOT_REACHED();
427 return LoadStatus::Error;
428}
429
430void FontFace::adopt(CSSFontFace& newFace)
431{
432 m_backing->removeClient(*this);
433 m_backing = newFace;
434 m_backing->addClient(*this);
435 newFace.setWrapper(*this);
436}
437
438void FontFace::fontStateChanged(CSSFontFace& face, CSSFontFace::Status, CSSFontFace::Status newState)
439{
440 ASSERT_UNUSED(face, &face == m_backing.ptr());
441 switch (newState) {
442 case CSSFontFace::Status::Loading:
443 break;
444 case CSSFontFace::Status::TimedOut:
445 break;
446 case CSSFontFace::Status::Success:
447 // FIXME: This check should not be needed, but because FontFace's are sometimes adopted after they have already
448 // gone through a load cycle, we can sometimes come back through here and try to resolve the promise again.
449 if (!m_loadedPromise->isFulfilled())
450 m_loadedPromise->resolve(*this);
451 return;
452 case CSSFontFace::Status::Failure:
453 // FIXME: This check should not be needed, but because FontFace's are sometimes adopted after they have already
454 // gone through a load cycle, we can sometimes come back through here and try to resolve the promise again.
455 if (!m_loadedPromise->isFulfilled())
456 m_loadedPromise->reject(Exception { NetworkError });
457 return;
458 case CSSFontFace::Status::Pending:
459 ASSERT_NOT_REACHED();
460 return;
461 }
462}
463
464auto FontFace::loadForBindings() -> LoadedPromise&
465{
466 m_mayLoadedPromiseBeScriptObservable = true;
467 m_backing->load();
468 return m_loadedPromise.get();
469}
470
471auto FontFace::loadedForBindings() -> LoadedPromise&
472{
473 m_mayLoadedPromiseBeScriptObservable = true;
474 return m_loadedPromise.get();
475}
476
477FontFace& FontFace::loadedPromiseResolve()
478{
479 return *this;
480}
481
482const char* FontFace::activeDOMObjectName() const
483{
484 return "FontFace";
485}
486
487bool FontFace::virtualHasPendingActivity() const
488{
489 return m_mayLoadedPromiseBeScriptObservable && !m_loadedPromise->isFulfilled();
490}
491
492}
Note: See TracBrowser for help on using the repository browser.