LibWeb: Track declared font width on @font-face rules

This commit is contained in:
Tim Ledbetter
2026-04-23 16:44:32 +01:00
committed by Andreas Kling
parent 5cefb14707
commit 2ff967fd6f
Notes: github-actions[bot] 2026-04-24 18:20:47 +00:00
4 changed files with 25 additions and 4 deletions

View File

@@ -465,6 +465,7 @@ NonnullRefPtr<Gfx::FontCascadeList const> FontComputer::compute_font_for_style_v
.family_name = family,
.weight = { weight, weight },
.slope = slope,
.width = static_cast<int>(font_width.value()),
};
if (auto it = m_font_faces.find(lookup_key); it != m_font_faces.end()) {
auto shape_features = font_feature_data.to_shape_features(font_feature_values);
@@ -657,6 +658,7 @@ void FontComputer::register_font_face(GC::Ref<FontFace> face)
.family_name = FlyString(face->family()),
.weight = face->declared_weight_range(),
.slope = face->declared_slope(),
.width = face->declared_width(),
};
auto& faces = m_font_faces.ensure(key);
if (!faces.contains_slow(face))
@@ -672,6 +674,7 @@ void FontComputer::unregister_font_face(GC::Ref<FontFace> face)
.family_name = FlyString(face->family()),
.weight = face->declared_weight_range(),
.slope = face->declared_slope(),
.width = face->declared_width(),
};
if (auto it = m_font_faces.find(key); it != m_font_faces.end()) {
it->value.remove_all_matching([&](auto const& entry) { return entry == face; });

View File

@@ -35,12 +35,14 @@ struct FontFaceKey {
FlyString family_name;
FontWeightRange weight;
int slope { 0 };
[[nodiscard]] u32 hash() const { return pair_int_hash(family_name.ascii_case_insensitive_hash(), pair_int_hash(weight.hash(), slope)); }
int width { 100 };
[[nodiscard]] u32 hash() const { return pair_int_hash(family_name.ascii_case_insensitive_hash(), pair_int_hash(weight.hash(), pair_int_hash(slope, width))); }
[[nodiscard]] bool operator==(FontFaceKey const& other) const
{
return family_name.equals_ignoring_ascii_case(other.family_name)
&& weight == other.weight
&& slope == other.slope;
&& slope == other.slope
&& width == other.width;
}
};

View File

@@ -77,6 +77,14 @@ static int compute_slope(StyleValue const& value)
return StyleComputer::compute_font_style(value)->as_font_style().to_font_slope();
}
static int compute_width(StyleValue const& value)
{
if (value.to_keyword() == Keyword::Auto || value.to_keyword() == Keyword::Normal)
return 100;
return static_cast<int>(StyleComputer::compute_font_width(value)->as_percentage().raw_value());
}
static NonnullRefPtr<Core::Promise<NonnullRefPtr<Gfx::Typeface const>>> load_vector_font([[maybe_unused]] JS::Realm& realm, ByteBuffer data)
{
auto promise = Core::Promise<NonnullRefPtr<Gfx::Typeface const>>::construct();
@@ -315,7 +323,7 @@ ParsedFontFace FontFace::parsed_font_face() const
m_family,
m_cached_weight_range,
m_cached_slope,
Gfx::FontWidth::Normal, // FIXME: width
m_cached_width,
m_urls,
m_unicode_ranges,
{}, // FIXME: ascent_override
@@ -516,11 +524,16 @@ WebIDL::ExceptionOr<void> FontFace::set_stretch(String const& string)
if (m_css_font_face_rule)
TRY(m_css_font_face_rule->descriptors()->set_font_width(string));
if (should_be_registered_with_font_computer()) {
if (auto font_computer = this->font_computer(); font_computer.has_value())
font_computer->unregister_font_face(*this);
}
set_stretch_impl(property.release_nonnull());
if (should_be_registered_with_font_computer()) {
if (auto font_computer = this->font_computer(); font_computer.has_value())
font_computer->did_load_font(FlyString(m_family));
font_computer->register_font_face(*this);
}
return {};
@@ -529,6 +542,7 @@ WebIDL::ExceptionOr<void> FontFace::set_stretch(String const& string)
void FontFace::set_stretch_impl(NonnullRefPtr<StyleValue const> const& value)
{
m_stretch = value->to_string(SerializationMode::Normal);
m_cached_width = compute_width(*value);
}
// https://drafts.csswg.org/css-font-loading/#dom-fontface-unicoderange

View File

@@ -95,6 +95,7 @@ public:
FontWeightRange declared_weight_range() const { return m_cached_weight_range; }
int declared_slope() const { return m_cached_slope; }
int declared_width() const { return m_cached_width; }
bool should_be_registered_with_font_computer() const { return is_css_connected() || status() == Bindings::FontFaceLoadStatus::Loaded; }
RefPtr<Gfx::FontCascadeList const> font_with_point_size(float point_size, Gfx::FontVariationSettings const&, Gfx::ShapeFeatures const&) const;
@@ -134,6 +135,7 @@ private:
FontWeightRange m_cached_weight_range { 400, 400 };
int m_cached_slope { 0 };
int m_cached_width { 100 };
GC::Ptr<FontLoader> m_font_loader;
// https://drafts.csswg.org/css-font-loading/#dom-fontface-status