1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 17:07:34 +00:00

LibWeb: Turn StyleProperties::m_property_values into an Array

After style computation, every StyleProperties has a value for every
PropertyID. Given this, it's simpler, faster and less memory-heavy to
use an Array instead of a HashMap. :^)
This commit is contained in:
Andreas Kling 2022-02-18 20:21:49 +01:00
parent eca8208a34
commit 141b01d3e3
3 changed files with 35 additions and 28 deletions

View file

@ -634,32 +634,29 @@ static NonnullRefPtr<StyleValue> get_inherit_value(CSS::PropertyID property_id,
{ {
if (!element || !element->parent_element() || !element->parent_element()->specified_css_values()) if (!element || !element->parent_element() || !element->parent_element()->specified_css_values())
return property_initial_value(property_id); return property_initial_value(property_id);
auto const& map = element->parent_element()->specified_css_values()->properties(); return element->parent_element()->specified_css_values()->property(property_id).release_value();
auto it = map.find(property_id);
VERIFY(it != map.end());
return *it->value;
}; };
void StyleComputer::compute_defaulted_property_value(StyleProperties& style, DOM::Element const* element, CSS::PropertyID property_id) const void StyleComputer::compute_defaulted_property_value(StyleProperties& style, DOM::Element const* element, CSS::PropertyID property_id) const
{ {
// FIXME: If we don't know the correct initial value for a property, we fall back to InitialStyleValue. // FIXME: If we don't know the correct initial value for a property, we fall back to InitialStyleValue.
auto it = style.m_property_values.find(property_id); auto& value_slot = style.m_property_values[to_underlying(property_id)];
if (it == style.m_property_values.end()) { if (!value_slot) {
if (is_inherited_property(property_id)) if (is_inherited_property(property_id))
style.m_property_values.set(property_id, get_inherit_value(property_id, element)); style.m_property_values[to_underlying(property_id)] = get_inherit_value(property_id, element);
else else
style.m_property_values.set(property_id, property_initial_value(property_id)); style.m_property_values[to_underlying(property_id)] = property_initial_value(property_id);
return; return;
} }
if (it->value->is_initial()) { if (value_slot->is_initial()) {
it->value = property_initial_value(property_id); value_slot = property_initial_value(property_id);
return; return;
} }
if (it->value->is_inherit()) { if (value_slot->is_inherit()) {
it->value = get_inherit_value(property_id, element); value_slot = get_inherit_value(property_id, element);
return; return;
} }
} }
@ -869,8 +866,10 @@ void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const
// FIXME: Get the root element font. // FIXME: Get the root element font.
float root_font_size = 10; float root_font_size = 10;
for (auto& it : style.properties()) { for (auto& value_slot : style.m_property_values) {
it.value->visit_lengths([&](Length& length) { if (!value_slot)
continue;
value_slot->visit_lengths([&](Length& length) {
if (length.is_absolute() || length.is_relative()) { if (length.is_absolute() || length.is_relative()) {
auto px = length.to_px(viewport_rect, font_metrics, root_font_size); auto px = length.to_px(viewport_rect, font_metrics, root_font_size);
length = Length::make_px(px); length = Length::make_px(px);

View file

@ -36,15 +36,15 @@ NonnullRefPtr<StyleProperties> StyleProperties::clone() const
void StyleProperties::set_property(CSS::PropertyID id, NonnullRefPtr<StyleValue> value) void StyleProperties::set_property(CSS::PropertyID id, NonnullRefPtr<StyleValue> value)
{ {
m_property_values.set(id, move(value)); m_property_values[to_underlying(id)] = move(value);
} }
Optional<NonnullRefPtr<StyleValue>> StyleProperties::property(CSS::PropertyID property_id) const Optional<NonnullRefPtr<StyleValue>> StyleProperties::property(CSS::PropertyID property_id) const
{ {
auto it = m_property_values.find(property_id); auto value = m_property_values[to_underlying(property_id)];
if (it == m_property_values.end()) if (!value)
return {}; return {};
return it->value; return value.release_nonnull();
} }
Length StyleProperties::length_or_fallback(CSS::PropertyID id, Length const& fallback) const Length StyleProperties::length_or_fallback(CSS::PropertyID id, Length const& fallback) const
@ -390,12 +390,18 @@ bool StyleProperties::operator==(const StyleProperties& other) const
if (m_property_values.size() != other.m_property_values.size()) if (m_property_values.size() != other.m_property_values.size())
return false; return false;
for (auto& it : m_property_values) { for (size_t i = 0; i < m_property_values.size(); ++i) {
auto jt = other.m_property_values.find(it.key); auto const& my_ptr = m_property_values[i];
if (jt == other.m_property_values.end()) auto const& other_ptr = m_property_values[i];
if (!my_ptr) {
if (other_ptr)
return false;
continue;
}
if (!other_ptr)
return false; return false;
auto& my_value = *it.value; auto const& my_value = *my_ptr;
auto& other_value = *jt->value; auto const& other_value = *other_ptr;
if (my_value.type() != other_value.type()) if (my_value.type() != other_value.type())
return false; return false;
if (my_value != other_value) if (my_value != other_value)

View file

@ -29,12 +29,14 @@ public:
template<typename Callback> template<typename Callback>
inline void for_each_property(Callback callback) const inline void for_each_property(Callback callback) const
{ {
for (auto& it : m_property_values) for (size_t i = 0; i < m_property_values.size(); ++i) {
callback((CSS::PropertyID)it.key, *it.value); if (m_property_values[i])
callback((CSS::PropertyID)i, *m_property_values[i]);
}
} }
HashMap<CSS::PropertyID, NonnullRefPtr<StyleValue>>& properties() { return m_property_values; } auto& properties() { return m_property_values; }
HashMap<CSS::PropertyID, NonnullRefPtr<StyleValue>> const& properties() const { return m_property_values; } auto const& properties() const { return m_property_values; }
void set_property(CSS::PropertyID, NonnullRefPtr<StyleValue> value); void set_property(CSS::PropertyID, NonnullRefPtr<StyleValue> value);
Optional<NonnullRefPtr<StyleValue>> property(CSS::PropertyID) const; Optional<NonnullRefPtr<StyleValue>> property(CSS::PropertyID) const;
@ -96,7 +98,7 @@ public:
private: private:
friend class StyleComputer; friend class StyleComputer;
HashMap<CSS::PropertyID, NonnullRefPtr<StyleValue>> m_property_values; Array<RefPtr<StyleValue>, to_underlying(CSS::last_property_id) + 1> m_property_values;
Optional<CSS::Overflow> overflow(CSS::PropertyID) const; Optional<CSS::Overflow> overflow(CSS::PropertyID) const;
mutable RefPtr<Gfx::Font> m_font; mutable RefPtr<Gfx::Font> m_font;