blob: 4c9ead5597652d1292685a1f3b522fde682d0eae [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/css/style_rule_font_feature_values.h"
#include "third_party/blink/renderer/core/css/cascade_layer.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include <limits>
namespace blink {
StyleRuleFontFeature::StyleRuleFontFeature(
StyleRuleFontFeature::FeatureType type)
: StyleRuleBase(kFontFeature), type_(type) {}
StyleRuleFontFeature::StyleRuleFontFeature(const StyleRuleFontFeature&) =
default;
StyleRuleFontFeature::~StyleRuleFontFeature() = default;
void StyleRuleFontFeature::TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleBase::TraceAfterDispatch(visitor);
}
void StyleRuleFontFeature::UpdateAlias(AtomicString alias,
const Vector<uint32_t>& features) {
feature_aliases_.Set(
alias, FeatureIndicesWithPriority{features,
std::numeric_limits<unsigned>::max()});
}
void StyleRuleFontFeature::OverrideAliasesIn(FontFeatureAliases& destination) {
for (const auto& hash_entry : feature_aliases_) {
destination.Set(hash_entry.key, hash_entry.value);
}
}
FontFeatureValuesStorage::FontFeatureValuesStorage(
FontFeatureAliases stylistic,
FontFeatureAliases styleset,
FontFeatureAliases character_variant,
FontFeatureAliases swash,
FontFeatureAliases ornaments,
FontFeatureAliases annotation)
: stylistic_(stylistic),
styleset_(styleset),
character_variant_(character_variant),
swash_(swash),
ornaments_(ornaments),
annotation_(annotation) {}
Vector<uint32_t> FontFeatureValuesStorage::ResolveStylistic(
AtomicString alias) const {
return ResolveInternal(stylistic_, alias);
}
Vector<uint32_t> FontFeatureValuesStorage::ResolveStyleset(
AtomicString alias) const {
return ResolveInternal(styleset_, alias);
}
Vector<uint32_t> FontFeatureValuesStorage::ResolveCharacterVariant(
AtomicString alias) const {
return ResolveInternal(character_variant_, alias);
}
Vector<uint32_t> FontFeatureValuesStorage::ResolveSwash(
AtomicString alias) const {
return ResolveInternal(swash_, alias);
}
Vector<uint32_t> FontFeatureValuesStorage::ResolveOrnaments(
AtomicString alias) const {
return ResolveInternal(ornaments_, alias);
}
Vector<uint32_t> FontFeatureValuesStorage::ResolveAnnotation(
AtomicString alias) const {
return ResolveInternal(annotation_, alias);
}
void FontFeatureValuesStorage::SetLayerOrder(unsigned layer_order) {
auto set_layer_order = [layer_order](FontFeatureAliases& aliases) {
for (auto& entry : aliases) {
entry.value.layer_order = layer_order;
}
};
set_layer_order(stylistic_);
set_layer_order(styleset_);
set_layer_order(character_variant_);
set_layer_order(swash_);
set_layer_order(ornaments_);
set_layer_order(annotation_);
}
void FontFeatureValuesStorage::FuseUpdate(const FontFeatureValuesStorage& other,
unsigned other_layer_order) {
auto merge_maps = [other_layer_order](FontFeatureAliases& own,
const FontFeatureAliases& other) {
for (auto entry : other) {
FeatureIndicesWithPriority entry_updated_order(entry.value);
entry_updated_order.layer_order = other_layer_order;
auto insert_result = own.insert(entry.key, entry_updated_order);
if (!insert_result.is_new_entry) {
unsigned existing_layer_order =
insert_result.stored_value->value.layer_order;
if (other_layer_order >= existing_layer_order) {
insert_result.stored_value->value = entry_updated_order;
}
}
}
};
merge_maps(stylistic_, other.stylistic_);
merge_maps(styleset_, other.styleset_);
merge_maps(character_variant_, other.character_variant_);
merge_maps(swash_, other.swash_);
merge_maps(ornaments_, other.ornaments_);
merge_maps(annotation_, other.annotation_);
}
/* static */
Vector<uint32_t> FontFeatureValuesStorage::ResolveInternal(
const FontFeatureAliases& aliases,
AtomicString alias) {
auto find_result = aliases.find(alias);
if (find_result == aliases.end()) {
return {};
}
return find_result->value.indices;
}
StyleRuleFontFeatureValues::StyleRuleFontFeatureValues(
Vector<AtomicString> families,
FontFeatureAliases stylistic,
FontFeatureAliases styleset,
FontFeatureAliases character_variant,
FontFeatureAliases swash,
FontFeatureAliases ornaments,
FontFeatureAliases annotation)
: StyleRuleBase(kFontFeatureValues),
families_(std::move(families)),
feature_values_storage_(stylistic,
styleset,
character_variant,
swash,
ornaments,
annotation) {}
StyleRuleFontFeatureValues::StyleRuleFontFeatureValues(
const StyleRuleFontFeatureValues&) = default;
StyleRuleFontFeatureValues::~StyleRuleFontFeatureValues() = default;
void StyleRuleFontFeatureValues::SetFamilies(Vector<AtomicString> families) {
families_ = std::move(families);
}
String StyleRuleFontFeatureValues::FamilyAsString() const {
StringBuilder families;
for (wtf_size_t i = 0; i < families_.size(); ++i) {
families.Append(families_[i]);
if (i < families_.size() - 1) {
families.Append(", ");
}
}
return families.ReleaseString();
}
void StyleRuleFontFeatureValues::TraceAfterDispatch(
blink::Visitor* visitor) const {
StyleRuleBase::TraceAfterDispatch(visitor);
visitor->Trace(layer_);
}
} // namespace blink