mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-05 07:39:16 +00:00
The StyleValue stored in m_property_values is already in it's computed form and it's trivial to pull the underlying value out so there is no need to store this separately. Also removes unnecessary handling of percentage values in `absolutize_values` - this is already handled within `compute_font`.
289 lines
12 KiB
C++
289 lines
12 KiB
C++
/*
|
|
* Copyright (c) 2018-2025, Andreas Kling <andreas@ladybird.org>
|
|
* Copyright (c) 2023-2025, Sam Atkins <sam@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/HashMap.h>
|
|
#include <AK/NonnullRefPtr.h>
|
|
#include <LibGC/CellAllocator.h>
|
|
#include <LibGC/Ptr.h>
|
|
#include <LibGfx/Font/Font.h>
|
|
#include <LibGfx/FontCascadeList.h>
|
|
#include <LibGfx/Forward.h>
|
|
#include <LibJS/Heap/Cell.h>
|
|
#include <LibWeb/CSS/ComputedValues.h>
|
|
#include <LibWeb/CSS/LengthBox.h>
|
|
#include <LibWeb/CSS/PropertyID.h>
|
|
#include <LibWeb/CSS/PseudoClass.h>
|
|
#include <LibWeb/CSS/PseudoClassBitmap.h>
|
|
#include <LibWeb/CSS/StyleProperty.h>
|
|
#include <LibWeb/Export.h>
|
|
|
|
namespace Web::CSS {
|
|
|
|
class WEB_API ComputedProperties final : public JS::Cell {
|
|
GC_CELL(ComputedProperties, JS::Cell);
|
|
GC_DECLARE_ALLOCATOR(ComputedProperties);
|
|
|
|
public:
|
|
static constexpr double normal_line_height_scale = 1.15;
|
|
static constexpr size_t number_of_properties = to_underlying(last_property_id) + 1;
|
|
|
|
virtual ~ComputedProperties() override;
|
|
|
|
template<typename Callback>
|
|
inline void for_each_property(Callback callback) const
|
|
{
|
|
for (size_t i = 0; i < m_property_values.size(); ++i) {
|
|
if (m_property_values[i])
|
|
callback((PropertyID)i, *m_property_values[i]);
|
|
}
|
|
}
|
|
|
|
enum class Inherited {
|
|
No,
|
|
Yes
|
|
};
|
|
|
|
HashMap<PropertyID, NonnullRefPtr<StyleValue const>> const& animated_property_values() const { return m_animated_property_values; }
|
|
void reset_animated_properties(Badge<Animations::KeyframeEffect>);
|
|
|
|
bool is_property_important(PropertyID property_id) const;
|
|
bool is_property_inherited(PropertyID property_id) const;
|
|
bool is_animated_property_inherited(PropertyID property_id) const;
|
|
void set_property_important(PropertyID, Important);
|
|
void set_property_inherited(PropertyID, Inherited);
|
|
void set_animated_property_inherited(PropertyID, Inherited);
|
|
|
|
void set_property(PropertyID, NonnullRefPtr<StyleValue const> value, Inherited = Inherited::No, Important = Important::No);
|
|
void set_animated_property(PropertyID, NonnullRefPtr<StyleValue const> value, Inherited = Inherited::No);
|
|
void remove_animated_property(PropertyID);
|
|
enum class WithAnimationsApplied {
|
|
No,
|
|
Yes,
|
|
};
|
|
StyleValue const& property(PropertyID, WithAnimationsApplied = WithAnimationsApplied::Yes) const;
|
|
StyleValue const* maybe_null_property(PropertyID) const;
|
|
void revert_property(PropertyID, ComputedProperties const& style_for_revert);
|
|
|
|
GC::Ptr<CSSStyleDeclaration const> animation_name_source() const { return m_animation_name_source; }
|
|
void set_animation_name_source(GC::Ptr<CSSStyleDeclaration const> declaration) { m_animation_name_source = declaration; }
|
|
|
|
GC::Ptr<CSSStyleDeclaration const> transition_property_source() const { return m_transition_property_source; }
|
|
void set_transition_property_source(GC::Ptr<CSSStyleDeclaration const> declaration) { m_transition_property_source = declaration; }
|
|
|
|
Size size_value(PropertyID) const;
|
|
[[nodiscard]] Variant<LengthPercentage, NormalGap> gap_value(PropertyID) const;
|
|
LengthPercentage length_percentage_or_fallback(PropertyID, LengthPercentage const& fallback) const;
|
|
Optional<LengthPercentage> length_percentage(PropertyID) const;
|
|
LengthBox length_box(PropertyID left_id, PropertyID top_id, PropertyID right_id, PropertyID bottom_id, Length const& default_value) const;
|
|
Color color_or_fallback(PropertyID, ColorResolutionContext, Color fallback) const;
|
|
ColorInterpolation color_interpolation() const;
|
|
PreferredColorScheme color_scheme(PreferredColorScheme, Optional<Vector<String> const&> document_supported_schemes) const;
|
|
TextAnchor text_anchor() const;
|
|
TextAlign text_align() const;
|
|
TextJustify text_justify() const;
|
|
TextOverflow text_overflow() const;
|
|
TextRendering text_rendering() const;
|
|
Length border_spacing_horizontal(Layout::Node const&) const;
|
|
Length border_spacing_vertical(Layout::Node const&) const;
|
|
CaptionSide caption_side() const;
|
|
Clip clip() const;
|
|
Display display() const;
|
|
Float float_() const;
|
|
Color caret_color(Layout::NodeWithStyle const&) const;
|
|
Clear clear() const;
|
|
ColumnSpan column_span() const;
|
|
struct ContentDataAndQuoteNestingLevel {
|
|
ContentData content_data;
|
|
u32 final_quote_nesting_level { 0 };
|
|
};
|
|
ContentDataAndQuoteNestingLevel content(DOM::AbstractElement&, u32 initial_quote_nesting_level) const;
|
|
ContentVisibility content_visibility() const;
|
|
Vector<CursorData> cursor() const;
|
|
Variant<LengthOrCalculated, NumberOrCalculated> tab_size() const;
|
|
WhiteSpaceCollapse white_space_collapse() const;
|
|
WhiteSpaceTrimData white_space_trim() const;
|
|
WordBreak word_break() const;
|
|
Optional<LengthPercentage> word_spacing() const;
|
|
Optional<LengthOrCalculated> letter_spacing() const;
|
|
LineStyle line_style(PropertyID) const;
|
|
OutlineStyle outline_style() const;
|
|
Vector<TextDecorationLine> text_decoration_line() const;
|
|
TextDecorationStyle text_decoration_style() const;
|
|
TextTransform text_transform() const;
|
|
Vector<ShadowData> text_shadow(Layout::Node const&) const;
|
|
TextWrapMode text_wrap_mode() const;
|
|
ListStyleType list_style_type() const;
|
|
ListStylePosition list_style_position() const;
|
|
FlexDirection flex_direction() const;
|
|
FlexWrap flex_wrap() const;
|
|
FlexBasis flex_basis() const;
|
|
float flex_grow() const;
|
|
float flex_shrink() const;
|
|
int order() const;
|
|
Optional<Color> accent_color(Layout::NodeWithStyle const&) const;
|
|
AlignContent align_content() const;
|
|
AlignItems align_items() const;
|
|
AlignSelf align_self() const;
|
|
Appearance appearance() const;
|
|
Filter backdrop_filter() const;
|
|
Filter filter() const;
|
|
float opacity() const;
|
|
Visibility visibility() const;
|
|
ImageRendering image_rendering() const;
|
|
JustifyContent justify_content() const;
|
|
JustifyItems justify_items() const;
|
|
JustifySelf justify_self() const;
|
|
Overflow overflow_x() const;
|
|
Overflow overflow_y() const;
|
|
Vector<ShadowData> box_shadow(Layout::Node const&) const;
|
|
BoxSizing box_sizing() const;
|
|
PointerEvents pointer_events() const;
|
|
Variant<VerticalAlign, LengthPercentage> vertical_align() const;
|
|
Optional<Gfx::FontVariantAlternates> font_variant_alternates() const;
|
|
FontVariantCaps font_variant_caps() const;
|
|
Optional<Gfx::FontVariantEastAsian> font_variant_east_asian() const;
|
|
FontVariantEmoji font_variant_emoji() const;
|
|
Optional<Gfx::FontVariantLigatures> font_variant_ligatures() const;
|
|
Optional<Gfx::FontVariantNumeric> font_variant_numeric() const;
|
|
FontVariantPosition font_variant_position() const;
|
|
FontKerning font_kerning() const;
|
|
Optional<FlyString> font_language_override() const;
|
|
Optional<HashMap<FlyString, IntegerOrCalculated>> font_feature_settings() const;
|
|
Optional<HashMap<FlyString, NumberOrCalculated>> font_variation_settings() const;
|
|
GridTrackSizeList grid_auto_columns() const;
|
|
GridTrackSizeList grid_auto_rows() const;
|
|
GridTrackSizeList grid_template_columns() const;
|
|
GridTrackSizeList grid_template_rows() const;
|
|
[[nodiscard]] GridAutoFlow grid_auto_flow() const;
|
|
GridTrackPlacement grid_column_end() const;
|
|
GridTrackPlacement grid_column_start() const;
|
|
GridTrackPlacement grid_row_end() const;
|
|
GridTrackPlacement grid_row_start() const;
|
|
BorderCollapse border_collapse() const;
|
|
CSS::EmptyCells empty_cells() const;
|
|
Vector<Vector<String>> grid_template_areas() const;
|
|
ObjectFit object_fit() const;
|
|
ObjectPosition object_position() const;
|
|
TableLayout table_layout() const;
|
|
Direction direction() const;
|
|
UnicodeBidi unicode_bidi() const;
|
|
WritingMode writing_mode() const;
|
|
UserSelect user_select() const;
|
|
Isolation isolation() const;
|
|
TouchActionData touch_action() const;
|
|
Containment contain() const;
|
|
MixBlendMode mix_blend_mode() const;
|
|
Optional<FlyString> view_transition_name() const;
|
|
|
|
static Vector<Transformation> transformations_for_style_value(StyleValue const& value);
|
|
Vector<Transformation> transformations() const;
|
|
TransformBox transform_box() const;
|
|
TransformOrigin transform_origin() const;
|
|
Optional<Transformation> rotate() const;
|
|
Optional<Transformation> translate() const;
|
|
Optional<Transformation> scale() const;
|
|
|
|
MaskType mask_type() const;
|
|
float stop_opacity() const;
|
|
float fill_opacity() const;
|
|
StrokeLinecap stroke_linecap() const;
|
|
StrokeLinejoin stroke_linejoin() const;
|
|
NumberOrCalculated stroke_miterlimit() const;
|
|
float stroke_opacity() const;
|
|
FillRule fill_rule() const;
|
|
ClipRule clip_rule() const;
|
|
float flood_opacity() const;
|
|
CSS::ShapeRendering shape_rendering() const;
|
|
|
|
WillChange will_change() const;
|
|
|
|
Gfx::FontCascadeList const& computed_font_list() const
|
|
{
|
|
VERIFY(m_font_list);
|
|
return *m_font_list;
|
|
}
|
|
|
|
Gfx::Font const& first_available_computed_font() const
|
|
{
|
|
VERIFY(m_first_available_computed_font);
|
|
return *m_first_available_computed_font;
|
|
}
|
|
|
|
void set_computed_font_list(NonnullRefPtr<Gfx::FontCascadeList const> font_list)
|
|
{
|
|
m_font_list = move(font_list);
|
|
// https://drafts.csswg.org/css-fonts/#first-available-font
|
|
// First font for which the character U+0020 (space) is not excluded by a unicode-range
|
|
m_first_available_computed_font = m_font_list->font_for_code_point(' ');
|
|
}
|
|
|
|
[[nodiscard]] CSSPixels compute_line_height(CSSPixelRect const& viewport_rect, Length::FontMetrics const& font_metrics, Length::FontMetrics const& root_font_metrics) const;
|
|
|
|
[[nodiscard]] CSSPixels line_height() const { return *m_line_height; }
|
|
void set_line_height(Badge<StyleComputer> const&, CSSPixels line_height) { m_line_height = line_height; }
|
|
[[nodiscard]] CSSPixels font_size() const;
|
|
|
|
bool operator==(ComputedProperties const&) const;
|
|
|
|
Positioning position() const;
|
|
Optional<int> z_index() const;
|
|
|
|
void set_math_depth(int math_depth);
|
|
int math_depth() const { return m_math_depth; }
|
|
|
|
QuotesData quotes() const;
|
|
Vector<CounterData> counter_data(PropertyID) const;
|
|
|
|
ScrollbarColorData scrollbar_color(Layout::NodeWithStyle const& layout_node) const;
|
|
ScrollbarWidth scrollbar_width() const;
|
|
|
|
static NonnullRefPtr<Gfx::Font const> font_fallback(bool monospace, bool bold, float point_size);
|
|
|
|
static float resolve_opacity_value(StyleValue const& value);
|
|
|
|
bool has_attempted_match_against_pseudo_class(PseudoClass pseudo_class) const
|
|
{
|
|
return m_attempted_pseudo_class_matches.get(pseudo_class);
|
|
}
|
|
|
|
void set_attempted_pseudo_class_matches(PseudoClassBitmap const& results)
|
|
{
|
|
m_attempted_pseudo_class_matches = results;
|
|
}
|
|
|
|
private:
|
|
friend class StyleComputer;
|
|
|
|
ComputedProperties();
|
|
|
|
virtual void visit_edges(Visitor&) override;
|
|
|
|
Overflow overflow(PropertyID) const;
|
|
Vector<ShadowData> shadow(PropertyID, Layout::Node const&) const;
|
|
|
|
GC::Ptr<CSSStyleDeclaration const> m_animation_name_source;
|
|
GC::Ptr<CSSStyleDeclaration const> m_transition_property_source;
|
|
|
|
Array<RefPtr<StyleValue const>, number_of_properties> m_property_values;
|
|
Array<u8, ceil_div(number_of_properties, 8uz)> m_property_important {};
|
|
Array<u8, ceil_div(number_of_properties, 8uz)> m_property_inherited {};
|
|
Array<u8, ceil_div(number_of_properties, 8uz)> m_animated_property_inherited {};
|
|
|
|
HashMap<PropertyID, NonnullRefPtr<StyleValue const>> m_animated_property_values;
|
|
|
|
int m_math_depth { InitialValues::math_depth() };
|
|
RefPtr<Gfx::FontCascadeList const> m_font_list;
|
|
RefPtr<Gfx::Font const> m_first_available_computed_font;
|
|
|
|
Optional<CSSPixels> m_line_height;
|
|
|
|
PseudoClassBitmap m_attempted_pseudo_class_matches;
|
|
};
|
|
|
|
}
|