
Once we've performed the cascade on a set of values for an element, we should have enough information to resolve/absolutize some lengths. Basically, any CSS length that isn't "auto" or a percentage can be turned into an absolute length (in pixels) as long as we have the following information: - The viewport rect - The parent element's font - The document element's font - The element's own font To ensure that we can absolutize lengths relative to the element's own font, we now do a separate first pass where font-related properties are defaulted (in the cascade spec sense of the word) and become usable. There's a lot more work to do here, but this should open up a lot of simplification in layout code, since it will no longer need to care about relative lengths. Layout still needs to resolve percentages, since we can't do that for some properties until the containing block dimensions are known.
111 lines
3.7 KiB
C++
111 lines
3.7 KiB
C++
/*
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/HashMap.h>
|
|
#include <AK/NonnullRefPtr.h>
|
|
#include <LibGfx/Font.h>
|
|
#include <LibGfx/Forward.h>
|
|
#include <LibWeb/CSS/ComputedValues.h>
|
|
#include <LibWeb/CSS/LengthBox.h>
|
|
#include <LibWeb/CSS/StyleValue.h>
|
|
|
|
namespace Web::CSS {
|
|
|
|
class StyleProperties : public RefCounted<StyleProperties> {
|
|
public:
|
|
StyleProperties();
|
|
|
|
explicit StyleProperties(const StyleProperties&);
|
|
|
|
static NonnullRefPtr<StyleProperties> create() { return adopt_ref(*new StyleProperties); }
|
|
|
|
NonnullRefPtr<StyleProperties> clone() const;
|
|
|
|
template<typename Callback>
|
|
inline void for_each_property(Callback callback) const
|
|
{
|
|
for (auto& it : m_property_values)
|
|
callback((CSS::PropertyID)it.key, *it.value);
|
|
}
|
|
|
|
HashMap<CSS::PropertyID, NonnullRefPtr<StyleValue>>& properties() { return m_property_values; }
|
|
HashMap<CSS::PropertyID, NonnullRefPtr<StyleValue>> const& properties() const { return m_property_values; }
|
|
|
|
void set_property(CSS::PropertyID, NonnullRefPtr<StyleValue> value);
|
|
void set_property(CSS::PropertyID, const StringView&);
|
|
Optional<NonnullRefPtr<StyleValue>> property(CSS::PropertyID) const;
|
|
|
|
Length length_or_fallback(CSS::PropertyID, const Length& fallback) const;
|
|
LengthBox length_box(CSS::PropertyID left_id, CSS::PropertyID top_id, CSS::PropertyID right_id, CSS::PropertyID bottom_id, const CSS::Length& default_value) const;
|
|
Color color_or_fallback(CSS::PropertyID, Layout::NodeWithStyle const&, Color fallback) const;
|
|
Optional<CSS::TextAlign> text_align() const;
|
|
CSS::Display display() const;
|
|
Optional<CSS::Float> float_() const;
|
|
Optional<CSS::Clear> clear() const;
|
|
Optional<CSS::Cursor> cursor() const;
|
|
Optional<CSS::WhiteSpace> white_space() const;
|
|
Optional<CSS::LineStyle> line_style(CSS::PropertyID) const;
|
|
Optional<CSS::TextDecorationLine> text_decoration_line() const;
|
|
Optional<CSS::TextTransform> text_transform() const;
|
|
Optional<CSS::ListStyleType> list_style_type() const;
|
|
Optional<CSS::FlexDirection> flex_direction() const;
|
|
Optional<CSS::FlexWrap> flex_wrap() const;
|
|
Optional<CSS::FlexBasisData> flex_basis() const;
|
|
Optional<float> flex_grow_factor() const;
|
|
Optional<float> flex_shrink_factor() const;
|
|
Optional<CSS::AlignItems> align_items() const;
|
|
Optional<float> opacity() const;
|
|
Optional<CSS::JustifyContent> justify_content() const;
|
|
Optional<CSS::Overflow> overflow_x() const;
|
|
Optional<CSS::Overflow> overflow_y() const;
|
|
Optional<CSS::Repeat> background_repeat_x() const;
|
|
Optional<CSS::Repeat> background_repeat_y() const;
|
|
Optional<CSS::BoxShadowData> box_shadow() const;
|
|
|
|
Vector<CSS::Transformation> transformations() const;
|
|
|
|
const Gfx::Font& font(Layout::Node const& node) const
|
|
{
|
|
if (!m_font)
|
|
load_font(node);
|
|
return *m_font;
|
|
}
|
|
|
|
Gfx::Font const& computed_font() const
|
|
{
|
|
VERIFY(m_font);
|
|
return *m_font;
|
|
}
|
|
|
|
void set_computed_font(NonnullRefPtr<Gfx::Font> font)
|
|
{
|
|
m_font = move(font);
|
|
}
|
|
|
|
float line_height(const Layout::Node&) const;
|
|
|
|
bool operator==(const StyleProperties&) const;
|
|
bool operator!=(const StyleProperties& other) const { return !(*this == other); }
|
|
|
|
Optional<CSS::Position> position() const;
|
|
Optional<int> z_index() const;
|
|
|
|
static NonnullRefPtr<Gfx::Font> font_fallback(bool monospace, bool bold);
|
|
|
|
private:
|
|
friend class StyleResolver;
|
|
|
|
HashMap<CSS::PropertyID, NonnullRefPtr<StyleValue>> m_property_values;
|
|
Optional<CSS::Overflow> overflow(CSS::PropertyID) const;
|
|
|
|
void load_font(Layout::Node const&) const;
|
|
|
|
mutable RefPtr<Gfx::Font> m_font;
|
|
};
|
|
|
|
}
|