/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/core/css/font_face.h"

#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer_or_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_font_face_descriptors.h"
#include "third_party/blink/renderer/core/css/binary_data_font_face_source.h"
#include "third_party/blink/renderer/core/css/css_font_face.h"
#include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
#include "third_party/blink/renderer/core/css/css_font_family_value.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/css_font_style_range_value.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_unicode_range_value.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/css_value_pair.h"
#include "third_party/blink/renderer/core/css/local_font_face_source.h"
#include "third_party/blink/renderer/core/css/offscreen_font_selector.h"
#include "third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h"
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
#include "third_party/blink/renderer/core/css/remote_font_face_source.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/css/style_rule.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/font_family_names.h"
#include "third_party/blink/renderer/platform/fonts/font_metrics_override.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"

namespace blink {

namespace {

const CSSValue* ParseCSSValue(const ExecutionContext* context,
                              const String& value,
                              AtRuleDescriptorID descriptor_id) {
  auto* window = DynamicTo<LocalDOMWindow>(context);
  CSSParserContext* parser_context =
      window ? MakeGarbageCollected<CSSParserContext>(*window->document())
             : MakeGarbageCollected<CSSParserContext>(*context);
  return AtRuleDescriptorParser::ParseFontFaceDescriptor(descriptor_id, value,
                                                         *parser_context);
}

CSSFontFace* CreateCSSFontFace(FontFace* font_face,
                               const CSSValue* unicode_range) {
  Vector<UnicodeRange> ranges;
  if (const auto* range_list = To<CSSValueList>(unicode_range)) {
    unsigned num_ranges = range_list->length();
    for (unsigned i = 0; i < num_ranges; i++) {
      const auto& range =
          To<cssvalue::CSSUnicodeRangeValue>(range_list->Item(i));
      ranges.push_back(UnicodeRange(range.From(), range.To()));
    }
  }

  return MakeGarbageCollected<CSSFontFace>(font_face, ranges);
}

const CSSValue* ConvertFontMetricOverrideValue(const CSSValue* parsed_value) {
  if (parsed_value && parsed_value->IsIdentifierValue()) {
    // We store the "normal" keyword value as nullptr
    DCHECK_EQ(CSSValueID::kNormal,
              To<CSSIdentifierValue>(parsed_value)->GetValueID());
    return nullptr;
  }
  return parsed_value;
}

}  // namespace

FontFace* FontFace::Create(ExecutionContext* context,
                           const AtomicString& family,
                           StringOrArrayBufferOrArrayBufferView& source,
                           const FontFaceDescriptors* descriptors) {
  if (source.IsString())
    return Create(context, family, source.GetAsString(), descriptors);
  if (source.IsArrayBuffer())
    return Create(context, family, source.GetAsArrayBuffer(), descriptors);
  if (source.IsArrayBufferView()) {
    return Create(context, family, source.GetAsArrayBufferView().Get(),
                  descriptors);
  }
  NOTREACHED();
  return nullptr;
}

FontFace* FontFace::Create(ExecutionContext* context,
                           const AtomicString& family,
                           const String& source,
                           const FontFaceDescriptors* descriptors) {
  FontFace* font_face =
      MakeGarbageCollected<FontFace>(context, family, descriptors);

  const CSSValue* src = ParseCSSValue(context, source, AtRuleDescriptorID::Src);
  if (!src || !src->IsValueList()) {
    font_face->SetError(MakeGarbageCollected<DOMException>(
        DOMExceptionCode::kSyntaxError,
        "The source provided ('" + source +
            "') could not be parsed as a value list."));
  }

  font_face->InitCSSFontFace(context, *src);
  return font_face;
}

FontFace* FontFace::Create(ExecutionContext* context,
                           const AtomicString& family,
                           DOMArrayBuffer* source,
                           const FontFaceDescriptors* descriptors) {
  FontFace* font_face =
      MakeGarbageCollected<FontFace>(context, family, descriptors);
  font_face->InitCSSFontFace(static_cast<const unsigned char*>(source->Data()),
                             source->ByteLength());
  return font_face;
}

FontFace* FontFace::Create(ExecutionContext* context,
                           const AtomicString& family,
                           DOMArrayBufferView* source,
                           const FontFaceDescriptors* descriptors) {
  FontFace* font_face =
      MakeGarbageCollected<FontFace>(context, family, descriptors);
  font_face->InitCSSFontFace(
      static_cast<const unsigned char*>(source->BaseAddress()),
      source->byteLength());
  return font_face;
}

FontFace* FontFace::Create(Document* document,
                           const StyleRuleFontFace* font_face_rule) {
  const CSSPropertyValueSet& properties = font_face_rule->Properties();

  // Obtain the font-family property and the src property. Both must be defined.
  const CSSValue* family =
      properties.GetPropertyCSSValue(AtRuleDescriptorID::FontFamily);
  if (!family || (!family->IsFontFamilyValue() && !family->IsIdentifierValue()))
    return nullptr;
  const CSSValue* src = properties.GetPropertyCSSValue(AtRuleDescriptorID::Src);
  if (!src || !src->IsValueList())
    return nullptr;

  FontFace* font_face =
      MakeGarbageCollected<FontFace>(document->GetExecutionContext());

  if (font_face->SetFamilyValue(*family) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::FontStyle) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::FontWeight) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::FontStretch) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::UnicodeRange) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::FontVariant) &&
      font_face->SetPropertyFromStyle(
          properties, AtRuleDescriptorID::FontFeatureSettings) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::FontDisplay) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::AscentOverride) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::DescentOverride) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::LineGapOverride) &&
      font_face->SetPropertyFromStyle(properties,
                                      AtRuleDescriptorID::AdvanceOverride) &&
      font_face->GetFontSelectionCapabilities().IsValid() &&
      !font_face->family().IsEmpty()) {
    font_face->InitCSSFontFace(document->GetExecutionContext(), *src);
    return font_face;
  }
  return nullptr;
}

FontFace::FontFace(ExecutionContext* context)
    : ExecutionContextClient(context), status_(kUnloaded) {}

FontFace::FontFace(ExecutionContext* context,
                   const AtomicString& family,
                   const FontFaceDescriptors* descriptors)
    : ExecutionContextClient(context), family_(family), status_(kUnloaded) {
  SetPropertyFromString(context, descriptors->style(),
                        AtRuleDescriptorID::FontStyle);
  SetPropertyFromString(context, descriptors->weight(),
                        AtRuleDescriptorID::FontWeight);
  SetPropertyFromString(context, descriptors->stretch(),
                        AtRuleDescriptorID::FontStretch);
  SetPropertyFromString(context, descriptors->unicodeRange(),
                        AtRuleDescriptorID::UnicodeRange);
  SetPropertyFromString(context, descriptors->variant(),
                        AtRuleDescriptorID::FontVariant);
  SetPropertyFromString(context, descriptors->featureSettings(),
                        AtRuleDescriptorID::FontFeatureSettings);
  SetPropertyFromString(context, descriptors->display(),
                        AtRuleDescriptorID::FontDisplay);
  if (RuntimeEnabledFeatures::CSSFontMetricsOverrideEnabled()) {
    SetPropertyFromString(context, descriptors->ascentOverride(),
                          AtRuleDescriptorID::AscentOverride);
    SetPropertyFromString(context, descriptors->descentOverride(),
                          AtRuleDescriptorID::DescentOverride);
    SetPropertyFromString(context, descriptors->lineGapOverride(),
                          AtRuleDescriptorID::LineGapOverride);
  }
}

FontFace::~FontFace() = default;

String FontFace::style() const {
  return style_ ? style_->CssText() : "normal";
}

String FontFace::weight() const {
  return weight_ ? weight_->CssText() : "normal";
}

String FontFace::stretch() const {
  return stretch_ ? stretch_->CssText() : "normal";
}

String FontFace::unicodeRange() const {
  return unicode_range_ ? unicode_range_->CssText() : "U+0-10FFFF";
}

String FontFace::variant() const {
  return variant_ ? variant_->CssText() : "normal";
}

String FontFace::featureSettings() const {
  return feature_settings_ ? feature_settings_->CssText() : "normal";
}

String FontFace::display() const {
  return display_ ? display_->CssText() : "auto";
}

String FontFace::ascentOverride() const {
  return ascent_override_ ? ascent_override_->CssText() : "normal";
}

String FontFace::descentOverride() const {
  return descent_override_ ? descent_override_->CssText() : "normal";
}

String FontFace::lineGapOverride() const {
  return line_gap_override_ ? line_gap_override_->CssText() : "normal";
}

void FontFace::setStyle(ExecutionContext* context,
                        const String& s,
                        ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::FontStyle,
                        &exception_state);
}

void FontFace::setWeight(ExecutionContext* context,
                         const String& s,
                         ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::FontWeight,
                        &exception_state);
}

void FontFace::setStretch(ExecutionContext* context,
                          const String& s,
                          ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::FontStretch,
                        &exception_state);
}

void FontFace::setUnicodeRange(ExecutionContext* context,
                               const String& s,
                               ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::UnicodeRange,
                        &exception_state);
}

void FontFace::setVariant(ExecutionContext* context,
                          const String& s,
                          ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::FontVariant,
                        &exception_state);
}

void FontFace::setFeatureSettings(ExecutionContext* context,
                                  const String& s,
                                  ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::FontFeatureSettings,
                        &exception_state);
}

void FontFace::setDisplay(ExecutionContext* context,
                          const String& s,
                          ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::FontDisplay,
                        &exception_state);
}

void FontFace::setAscentOverride(ExecutionContext* context,
                                 const String& s,
                                 ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::AscentOverride,
                        &exception_state);
}

void FontFace::setDescentOverride(ExecutionContext* context,
                                  const String& s,
                                  ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::DescentOverride,
                        &exception_state);
}

void FontFace::setLineGapOverride(ExecutionContext* context,
                                  const String& s,
                                  ExceptionState& exception_state) {
  SetPropertyFromString(context, s, AtRuleDescriptorID::LineGapOverride,
                        &exception_state);
}

void FontFace::SetPropertyFromString(const ExecutionContext* context,
                                     const String& s,
                                     AtRuleDescriptorID descriptor_id,
                                     ExceptionState* exception_state) {
  const CSSValue* value = ParseCSSValue(context, s, descriptor_id);
  if (value && SetPropertyValue(value, descriptor_id))
    return;

  String message = "Failed to set '" + s + "' as a property value.";
  if (exception_state) {
    exception_state->ThrowDOMException(DOMExceptionCode::kSyntaxError, message);
  } else {
    SetError(MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError,
                                                message));
  }
}

bool FontFace::SetPropertyFromStyle(const CSSPropertyValueSet& properties,
                                    AtRuleDescriptorID property_id) {
  return SetPropertyValue(properties.GetPropertyCSSValue(property_id),
                          property_id);
}

bool FontFace::SetPropertyValue(const CSSValue* value,
                                AtRuleDescriptorID descriptor_id) {
  switch (descriptor_id) {
    case AtRuleDescriptorID::FontStyle:
      style_ = value;
      break;
    case AtRuleDescriptorID::FontWeight:
      weight_ = value;
      break;
    case AtRuleDescriptorID::FontStretch:
      stretch_ = value;
      break;
    case AtRuleDescriptorID::UnicodeRange:
      if (value && !value->IsValueList())
        return false;
      unicode_range_ = value;
      break;
    case AtRuleDescriptorID::FontVariant:
      variant_ = value;
      break;
    case AtRuleDescriptorID::FontFeatureSettings:
      feature_settings_ = value;
      break;
    case AtRuleDescriptorID::FontDisplay:
      display_ = value;
      if (css_font_face_)
        css_font_face_->SetDisplay(CSSValueToFontDisplay(display_.Get()));
      break;
    case AtRuleDescriptorID::AscentOverride:
      ascent_override_ = ConvertFontMetricOverrideValue(value);
      break;
    case AtRuleDescriptorID::DescentOverride:
      descent_override_ = ConvertFontMetricOverrideValue(value);
      break;
    case AtRuleDescriptorID::LineGapOverride:
      line_gap_override_ = ConvertFontMetricOverrideValue(value);
      break;
    case AtRuleDescriptorID::AdvanceOverride:
      advance_override_ = ConvertFontMetricOverrideValue(value);
      break;
    default:
      NOTREACHED();
      return false;
  }
  return true;
}

bool FontFace::SetFamilyValue(const CSSValue& value) {
  AtomicString family;
  if (auto* family_value = DynamicTo<CSSFontFamilyValue>(value)) {
    family = AtomicString(family_value->Value());
  } else if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) {
    // 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 (identifier_value->GetValueID()) {
      case CSSValueID::kSerif:
        family = font_family_names::kWebkitSerif;
        break;
      case CSSValueID::kSansSerif:
        family = font_family_names::kWebkitSansSerif;
        break;
      case CSSValueID::kCursive:
        family = font_family_names::kWebkitCursive;
        break;
      case CSSValueID::kFantasy:
        family = font_family_names::kWebkitFantasy;
        break;
      case CSSValueID::kMonospace:
        family = font_family_names::kWebkitMonospace;
        break;
      default:
        return false;
    }
  }
  family_ = family;
  return true;
}

String FontFace::status() const {
  switch (status_) {
    case kUnloaded:
      return "unloaded";
    case kLoading:
      return "loading";
    case kLoaded:
      return "loaded";
    case kError:
      return "error";
    default:
      NOTREACHED();
  }
  return g_empty_string;
}

void FontFace::SetLoadStatus(LoadStatusType status) {
  status_ = status;
  DCHECK(status_ != kError || error_);

  if (!GetExecutionContext())
    return;

  if (status_ == kLoaded || status_ == kError) {
    if (loaded_property_) {
      if (status_ == kLoaded) {
        GetExecutionContext()
            ->GetTaskRunner(TaskType::kDOMManipulation)
            ->PostTask(FROM_HERE,
                       WTF::Bind(&LoadedProperty::Resolve<FontFace*>,
                                 WrapPersistent(loaded_property_.Get()),
                                 WrapPersistent(this)));
      } else {
        GetExecutionContext()
            ->GetTaskRunner(TaskType::kDOMManipulation)
            ->PostTask(FROM_HERE,
                       WTF::Bind(&LoadedProperty::Reject<DOMException*>,
                                 WrapPersistent(loaded_property_.Get()),
                                 WrapPersistent(error_.Get())));
      }
    }

    GetExecutionContext()
        ->GetTaskRunner(TaskType::kDOMManipulation)
        ->PostTask(FROM_HERE,
                   WTF::Bind(&FontFace::RunCallbacks, WrapPersistent(this)));
  }
}

void FontFace::RunCallbacks() {
  HeapVector<Member<LoadFontCallback>> callbacks;
  callbacks_.swap(callbacks);
  for (wtf_size_t i = 0; i < callbacks.size(); ++i) {
    if (status_ == kLoaded)
      callbacks[i]->NotifyLoaded(this);
    else
      callbacks[i]->NotifyError(this);
  }
}

void FontFace::SetError(DOMException* error) {
  if (!error_) {
    error_ = error ? error
                   : MakeGarbageCollected<DOMException>(
                         DOMExceptionCode::kNetworkError);
  }
  SetLoadStatus(kError);
}

ScriptPromise FontFace::FontStatusPromise(ScriptState* script_state) {
  if (!loaded_property_) {
    loaded_property_ = MakeGarbageCollected<LoadedProperty>(
        ExecutionContext::From(script_state));
    if (status_ == kLoaded)
      loaded_property_->Resolve(this);
    else if (status_ == kError)
      loaded_property_->Reject(error_.Get());
  }
  return loaded_property_->Promise(script_state->World());
}

ScriptPromise FontFace::load(ScriptState* script_state) {
  if (status_ == kUnloaded)
    css_font_face_->Load();
  DidBeginImperativeLoad();
  return FontStatusPromise(script_state);
}

void FontFace::LoadWithCallback(LoadFontCallback* callback) {
  if (status_ == kUnloaded)
    css_font_face_->Load();
  AddCallback(callback);
}

void FontFace::AddCallback(LoadFontCallback* callback) {
  if (status_ == kLoaded)
    callback->NotifyLoaded(this);
  else if (status_ == kError)
    callback->NotifyError(this);
  else
    callbacks_.push_back(callback);
}

FontSelectionCapabilities FontFace::GetFontSelectionCapabilities() const {
  // FontSelectionCapabilities represents a range of available width, slope and
  // weight values. The first value of each pair is the minimum value, the
  // second is the maximum value.
  FontSelectionCapabilities normal_capabilities(
      {NormalWidthValue(), NormalWidthValue()},
      {NormalSlopeValue(), NormalSlopeValue()},
      {NormalWeightValue(), NormalWeightValue()});
  FontSelectionCapabilities capabilities(normal_capabilities);

  if (stretch_) {
    if (auto* stretch_identifier_value =
            DynamicTo<CSSIdentifierValue>(stretch_.Get())) {
      switch (stretch_identifier_value->GetValueID()) {
        case CSSValueID::kUltraCondensed:
          capabilities.width = {UltraCondensedWidthValue(),
                                UltraCondensedWidthValue()};
          break;
        case CSSValueID::kExtraCondensed:
          capabilities.width = {ExtraCondensedWidthValue(),
                                ExtraCondensedWidthValue()};
          break;
        case CSSValueID::kCondensed:
          capabilities.width = {CondensedWidthValue(), CondensedWidthValue()};
          break;
        case CSSValueID::kSemiCondensed:
          capabilities.width = {SemiCondensedWidthValue(),
                                SemiCondensedWidthValue()};
          break;
        case CSSValueID::kSemiExpanded:
          capabilities.width = {SemiExpandedWidthValue(),
                                SemiExpandedWidthValue()};
          break;
        case CSSValueID::kExpanded:
          capabilities.width = {ExpandedWidthValue(), ExpandedWidthValue()};
          break;
        case CSSValueID::kExtraExpanded:
          capabilities.width = {ExtraExpandedWidthValue(),
                                ExtraExpandedWidthValue()};
          break;
        case CSSValueID::kUltraExpanded:
          capabilities.width = {UltraExpandedWidthValue(),
                                UltraExpandedWidthValue()};
          break;
        default:
          break;
      }
    } else if (const auto* stretch_list =
                   DynamicTo<CSSValueList>(stretch_.Get())) {
      // Transition FontFace interpretation of parsed values from
      // CSSIdentifierValue to CSSValueList or CSSPrimitiveValue.
      // TODO(drott) crbug.com/739139: Update the parser to only produce
      // CSSPrimitiveValue or CSSValueList.
      if (stretch_list->length() != 2)
        return normal_capabilities;
      const auto* stretch_from =
          DynamicTo<CSSPrimitiveValue>(&stretch_list->Item(0));
      const auto* stretch_to =
          DynamicTo<CSSPrimitiveValue>(&stretch_list->Item(1));
      if (!stretch_from || !stretch_to)
        return normal_capabilities;
      if (!stretch_from->IsPercentage() || !stretch_to->IsPercentage())
        return normal_capabilities;
      // https://drafts.csswg.org/css-fonts/#font-prop-desc
      // "User agents must swap the computed value of the startpoint and
      // endpoint of the range in order to forbid decreasing ranges."
      if (stretch_from->GetFloatValue() < stretch_to->GetFloatValue()) {
        capabilities.width = {FontSelectionValue(stretch_from->GetFloatValue()),
                              FontSelectionValue(stretch_to->GetFloatValue())};
      } else {
        capabilities.width = {
            FontSelectionValue(stretch_to->GetFloatValue()),
            FontSelectionValue(stretch_from->GetFloatValue())};
      }
    } else if (auto* stretch_primitive_value =
                   DynamicTo<CSSPrimitiveValue>(stretch_.Get())) {
      float stretch_value = stretch_primitive_value->GetFloatValue();
      capabilities.width = {FontSelectionValue(stretch_value),
                            FontSelectionValue(stretch_value)};
    } else {
      NOTREACHED();
      return normal_capabilities;
    }
  }

  if (style_) {
    if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(style_.Get())) {
      switch (identifier_value->GetValueID()) {
        case CSSValueID::kNormal:
          capabilities.slope = {NormalSlopeValue(), NormalSlopeValue()};
          break;
        case CSSValueID::kOblique:
          capabilities.slope = {ItalicSlopeValue(), ItalicSlopeValue()};
          break;
        case CSSValueID::kItalic:
          capabilities.slope = {ItalicSlopeValue(), ItalicSlopeValue()};
          break;
        default:
          break;
      }
    } else if (const auto* range_value =
                   DynamicTo<cssvalue::CSSFontStyleRangeValue>(style_.Get())) {
      if (range_value->GetFontStyleValue()->IsIdentifierValue()) {
        CSSValueID font_style_id =
            range_value->GetFontStyleValue()->GetValueID();
        if (!range_value->GetObliqueValues()) {
          if (font_style_id == CSSValueID::kNormal)
            capabilities.slope = {NormalSlopeValue(), NormalSlopeValue()};
          DCHECK(font_style_id == CSSValueID::kItalic ||
                 font_style_id == CSSValueID::kOblique);
          capabilities.slope = {ItalicSlopeValue(), ItalicSlopeValue()};
        } else {
          DCHECK(font_style_id == CSSValueID::kOblique);
          size_t oblique_values_size =
              range_value->GetObliqueValues()->length();
          if (oblique_values_size == 1) {
            const auto& range_start =
                To<CSSPrimitiveValue>(range_value->GetObliqueValues()->Item(0));
            FontSelectionValue oblique_range(range_start.GetFloatValue());
            capabilities.slope = {oblique_range, oblique_range};
          } else {
            DCHECK_EQ(oblique_values_size, 2u);
            const auto& range_start =
                To<CSSPrimitiveValue>(range_value->GetObliqueValues()->Item(0));
            const auto& range_end =
                To<CSSPrimitiveValue>(range_value->GetObliqueValues()->Item(1));
            // https://drafts.csswg.org/css-fonts/#font-prop-desc
            // "User agents must swap the computed value of the startpoint and
            // endpoint of the range in order to forbid decreasing ranges."
            if (range_start.GetFloatValue() < range_end.GetFloatValue()) {
              capabilities.slope = {
                  FontSelectionValue(range_start.GetFloatValue()),
                  FontSelectionValue(range_end.GetFloatValue())};
            } else {
              capabilities.slope = {
                  FontSelectionValue(range_end.GetFloatValue()),
                  FontSelectionValue(range_start.GetFloatValue())};
            }
          }
        }
      }
    } else {
      NOTREACHED();
      return normal_capabilities;
    }
  }

  if (weight_) {
    if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(weight_.Get())) {
      switch (identifier_value->GetValueID()) {
        // Although 'lighter' and 'bolder' are valid keywords for
        // font-weights, they are invalid inside font-face rules so they are
        // ignored. Reference:
        // http://www.w3.org/TR/css3-fonts/#descdef-font-weight.
        case CSSValueID::kLighter:
        case CSSValueID::kBolder:
          break;
        case CSSValueID::kNormal:
          capabilities.weight = {NormalWeightValue(), NormalWeightValue()};
          break;
        case CSSValueID::kBold:
          capabilities.weight = {BoldWeightValue(), BoldWeightValue()};
          break;
        default:
          NOTREACHED();
          break;
      }
    } else if (const auto* weight_list =
                   DynamicTo<CSSValueList>(weight_.Get())) {
      if (weight_list->length() != 2)
        return normal_capabilities;
      const auto* weight_from =
          DynamicTo<CSSPrimitiveValue>(&weight_list->Item(0));
      const auto* weight_to =
          DynamicTo<CSSPrimitiveValue>(&weight_list->Item(1));
      if (!weight_from || !weight_to)
        return normal_capabilities;
      if (!weight_from->IsNumber() || !weight_to->IsNumber() ||
          weight_from->GetFloatValue() < 1 || weight_to->GetFloatValue() > 1000)
        return normal_capabilities;
      // https://drafts.csswg.org/css-fonts/#font-prop-desc
      // "User agents must swap the computed value of the startpoint and
      // endpoint of the range in order to forbid decreasing ranges."
      if (weight_from->GetFloatValue() < weight_to->GetFloatValue()) {
        capabilities.weight = {FontSelectionValue(weight_from->GetFloatValue()),
                               FontSelectionValue(weight_to->GetFloatValue())};
      } else {
        capabilities.weight = {
            FontSelectionValue(weight_to->GetFloatValue()),
            FontSelectionValue(weight_from->GetFloatValue())};
      }
    } else if (auto* weight_primitive_value =
                   DynamicTo<CSSPrimitiveValue>(weight_.Get())) {
      float weight_value = weight_primitive_value->GetFloatValue();
      if (weight_value < 1 || weight_value > 1000)
        return normal_capabilities;
      capabilities.weight = {FontSelectionValue(weight_value),
                             FontSelectionValue(weight_value)};
    } else {
      NOTREACHED();
      return normal_capabilities;
    }
  }

  return capabilities;
}

size_t FontFace::ApproximateBlankCharacterCount() const {
  if (status_ == kLoading)
    return css_font_face_->ApproximateBlankCharacterCount();
  return 0;
}

bool ContextAllowsDownload(ExecutionContext* context) {
  if (!context) {
    return false;
  }
  if (const auto* window = DynamicTo<LocalDOMWindow>(context)) {
    const Settings* settings =
        window->GetFrame() ? window->GetFrame()->GetSettings() : nullptr;
    return settings && settings->GetDownloadableBinaryFontsEnabled();
  }
  // TODO(fserb): ideally, we would like to have the settings value available
  // on workers. Right now, we don't support that.
  return true;
}

void FontFace::InitCSSFontFace(ExecutionContext* context, const CSSValue& src) {
  css_font_face_ = CreateCSSFontFace(this, unicode_range_.Get());
  if (error_)
    return;

  // Each item in the src property's list is a single CSSFontFaceSource. Put
  // them all into a CSSFontFace.
  const auto& src_list = To<CSSValueList>(src);
  int src_length = src_list.length();

  for (int i = 0; i < src_length; i++) {
    // An item in the list either specifies a string (local font name) or a URL
    // (remote font to download).
    const CSSFontFaceSrcValue& item = To<CSSFontFaceSrcValue>(src_list.Item(i));

    FontSelector* font_selector = nullptr;
    if (auto* window = DynamicTo<LocalDOMWindow>(context)) {
      font_selector = window->document()->GetStyleEngine().GetFontSelector();
    } else if (auto* scope = DynamicTo<WorkerGlobalScope>(context)) {
      font_selector = scope->GetFontSelector();
    } else {
      NOTREACHED();
    }
    if (!item.IsLocal()) {
      if (ContextAllowsDownload(context) && item.IsSupportedFormat()) {
        RemoteFontFaceSource* source =
            MakeGarbageCollected<RemoteFontFaceSource>(
                css_font_face_, font_selector,
                CSSValueToFontDisplay(display_.Get()));
        item.Fetch(context, source);
        css_font_face_->AddSource(source);
      }
    } else {
      css_font_face_->AddSource(MakeGarbageCollected<LocalFontFaceSource>(
          css_font_face_, font_selector, item.GetResource()));
    }
  }

  if (display_) {
    UMA_HISTOGRAM_ENUMERATION("WebFont.FontDisplayValue",
                              CSSValueToFontDisplay(display_.Get()));
  }
}

void FontFace::InitCSSFontFace(const unsigned char* data, size_t size) {
  css_font_face_ = CreateCSSFontFace(this, unicode_range_.Get());
  if (error_)
    return;

  scoped_refptr<SharedBuffer> buffer = SharedBuffer::Create(data, size);
  BinaryDataFontFaceSource* source =
      MakeGarbageCollected<BinaryDataFontFaceSource>(
          css_font_face_, buffer.get(), ots_parse_message_);
  if (source->IsValid()) {
    SetLoadStatus(kLoaded);
  } else {
    SetError(MakeGarbageCollected<DOMException>(
        DOMExceptionCode::kSyntaxError, "Invalid font data in ArrayBuffer."));
  }
  css_font_face_->AddSource(source);
}

void FontFace::Trace(Visitor* visitor) const {
  visitor->Trace(style_);
  visitor->Trace(weight_);
  visitor->Trace(stretch_);
  visitor->Trace(unicode_range_);
  visitor->Trace(variant_);
  visitor->Trace(feature_settings_);
  visitor->Trace(display_);
  visitor->Trace(ascent_override_);
  visitor->Trace(descent_override_);
  visitor->Trace(line_gap_override_);
  visitor->Trace(advance_override_);
  visitor->Trace(error_);
  visitor->Trace(loaded_property_);
  visitor->Trace(css_font_face_);
  visitor->Trace(callbacks_);
  ScriptWrappable::Trace(visitor);
  ExecutionContextClient::Trace(visitor);
}

bool FontFace::HadBlankText() const {
  return css_font_face_->HadBlankText();
}

bool FontFace::HasPendingActivity() const {
  return status_ == kLoading && GetExecutionContext();
}

FontDisplay FontFace::GetFontDisplay() const {
  return CSSValueToFontDisplay(display_.Get());
}

void FontFace::DidBeginImperativeLoad() {
  if (!DomWindow())
    return;
  DomWindow()->document()->GetFontPreloadManager().ImperativeFontLoadingStarted(
      this);
}

FontMetricsOverride FontFace::GetFontMetricsOverride() const {
  FontMetricsOverride result;
  if (ascent_override_) {
    result.ascent_override =
        To<CSSPrimitiveValue>(*ascent_override_).GetFloatValue() / 100;
  }
  if (descent_override_) {
    result.descent_override =
        To<CSSPrimitiveValue>(*descent_override_).GetFloatValue() / 100;
  }
  if (line_gap_override_) {
    result.line_gap_override =
        To<CSSPrimitiveValue>(*line_gap_override_).GetFloatValue() / 100;
  }
  if (advance_override_) {
    const CSSValuePair& pair = To<CSSValuePair>(*advance_override_);
    result.advance_override =
        To<CSSPrimitiveValue>(pair.First()).GetFloatValue() / 100;
    result.advance_override_vertical_upright =
        To<CSSPrimitiveValue>(pair.Second()).GetFloatValue() / 100;
  }
  return result;
}

}  // namespace blink
