diff options
Diffstat (limited to 'Libraries/LibWeb')
-rw-r--r-- | Libraries/LibWeb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/Length.cpp | 64 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/Length.h | 27 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/StyleProperties.cpp | 4 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/StyleProperties.h | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/StyleResolver.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/StyleValue.h | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/Dump.cpp | 24 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/BoxModelMetrics.cpp | 10 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/BoxModelMetrics.h | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutBlock.cpp | 53 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutBox.cpp | 20 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutNode.cpp | 7 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutNode.h | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutReplaced.cpp | 25 | ||||
-rw-r--r-- | Libraries/LibWeb/Parser/CSSParser.cpp | 10 |
16 files changed, 163 insertions, 92 deletions
diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index b66a84ab52..3ba2a05983 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -17,6 +17,7 @@ set(SOURCES Bindings/XMLHttpRequestConstructor.cpp Bindings/XMLHttpRequestPrototype.cpp Bindings/XMLHttpRequestWrapper.cpp + CSS/Length.cpp CSS/Selector.cpp CSS/SelectorEngine.cpp CSS/StyleDeclaration.cpp diff --git a/Libraries/LibWeb/CSS/Length.cpp b/Libraries/LibWeb/CSS/Length.cpp new file mode 100644 index 0000000000..698608b836 --- /dev/null +++ b/Libraries/LibWeb/CSS/Length.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/CSS/Length.h> +#include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/HTMLHtmlElement.h> + +namespace Web { + +float Length::to_px(const LayoutNode& layout_node) const +{ + switch (m_type) { + case Type::Auto: + return 0; + case Type::Px: + return m_value; + case Type::Em: + return m_value * layout_node.font_size(); + case Type::Rem: + return m_value * layout_node.document().document_element()->layout_node()->font_size(); + default: + ASSERT_NOT_REACHED(); + } +} + +const char* Length::unit_name() const +{ + switch (m_type) { + case Type::Px: + return "px"; + case Type::Em: + return "em"; + case Type::Rem: + return "rem"; + case Type::Auto: + return "auto"; + } + ASSERT_NOT_REACHED(); +} + +} diff --git a/Libraries/LibWeb/CSS/Length.h b/Libraries/LibWeb/CSS/Length.h index 612c1cf49f..c63bd15345 100644 --- a/Libraries/LibWeb/CSS/Length.h +++ b/Libraries/LibWeb/CSS/Length.h @@ -27,6 +27,7 @@ #pragma once #include <AK/String.h> +#include <LibWeb/Forward.h> namespace Web { @@ -34,10 +35,12 @@ class Length { public: enum class Type { Auto, - Absolute, + Px, + Em, + Rem, }; - Length() {} + Length() { } Length(int value, Type type) : m_type(type) , m_value(value) @@ -48,28 +51,24 @@ public: , m_value(value) { } - ~Length() {} bool is_auto() const { return m_type == Type::Auto; } - bool is_absolute() const { return m_type == Type::Absolute; } + bool is_absolute() const { return m_type == Type::Px; } + bool is_relative() const { return m_type == Type::Em || m_type == Type::Rem; } - float value() const { return m_value; } + float raw_value() const { return m_value; } + float to_px(const LayoutNode&) const; String to_string() const { if (is_auto()) - return "[Length/auto]"; - return String::format("%g [Length/px]", m_value); - } - - float to_px() const - { - if (is_auto()) - return 0; - return m_value; + return "[auto]"; + return String::format("[%g %s]", m_value, unit_name()); } private: + const char* unit_name() const; + Type m_type { Type::Auto }; float m_value { 0 }; }; diff --git a/Libraries/LibWeb/CSS/StyleProperties.cpp b/Libraries/LibWeb/CSS/StyleProperties.cpp index c4b307803e..b2e2a02037 100644 --- a/Libraries/LibWeb/CSS/StyleProperties.cpp +++ b/Libraries/LibWeb/CSS/StyleProperties.cpp @@ -172,11 +172,11 @@ void StyleProperties::load_font() const return; } -float StyleProperties::line_height() const +float StyleProperties::line_height(const LayoutNode& layout_node) const { auto line_height_length = length_or_fallback(CSS::PropertyID::LineHeight, {}); if (line_height_length.is_absolute()) - return (float)line_height_length.to_px(); + return (float)line_height_length.to_px(layout_node); return (float)font().glyph_height() * 1.4f; } diff --git a/Libraries/LibWeb/CSS/StyleProperties.h b/Libraries/LibWeb/CSS/StyleProperties.h index 0b32443415..c45c2eddc2 100644 --- a/Libraries/LibWeb/CSS/StyleProperties.h +++ b/Libraries/LibWeb/CSS/StyleProperties.h @@ -66,7 +66,7 @@ public: return *m_font; } - float line_height() const; + float line_height(const LayoutNode&) const; bool operator==(const StyleProperties&) const; bool operator!=(const StyleProperties& other) const { return !(*this == other); } diff --git a/Libraries/LibWeb/CSS/StyleResolver.cpp b/Libraries/LibWeb/CSS/StyleResolver.cpp index dc6bfe7ea0..28ca825e26 100644 --- a/Libraries/LibWeb/CSS/StyleResolver.cpp +++ b/Libraries/LibWeb/CSS/StyleResolver.cpp @@ -190,7 +190,7 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope if (auto value = parse_line_style(parts[0])) { set_property_border_style(style, value.release_nonnull()); set_property_border_color(style, ColorStyleValue::create(Gfx::Color::Black)); - set_property_border_width(style, LengthStyleValue::create(Length(3, Length::Type::Absolute))); + set_property_border_width(style, LengthStyleValue::create(Length(3, Length::Type::Px))); return; } } diff --git a/Libraries/LibWeb/CSS/StyleValue.h b/Libraries/LibWeb/CSS/StyleValue.h index 64bde2e3c5..8186eddc5b 100644 --- a/Libraries/LibWeb/CSS/StyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValue.h @@ -212,7 +212,7 @@ public: virtual String to_string() const override { return String::format("%g%%", m_percentage); } - Length to_length(float reference) const { return Length((m_percentage / 100.0f) * reference, Length::Type::Absolute); } + Length to_length(float reference) const { return Length((m_percentage / 100.0f) * reference, Length::Type::Px); } private: virtual Length to_length() const override { return {}; } diff --git a/Libraries/LibWeb/Dump.cpp b/Libraries/LibWeb/Dump.cpp index c6173c1696..7d8f3733e8 100644 --- a/Libraries/LibWeb/Dump.cpp +++ b/Libraries/LibWeb/Dump.cpp @@ -117,23 +117,23 @@ void dump_tree(const LayoutNode& layout_node) // Dump the horizontal box properties dbgprintf(" [%g+%g+%g %g %g+%g+%g]", - layout_box.box_model().margin().left.to_px(), - layout_box.box_model().border().left.to_px(), - layout_box.box_model().padding().left.to_px(), + layout_box.box_model().margin().left.to_px(layout_box), + layout_box.box_model().border().left.to_px(layout_box), + layout_box.box_model().padding().left.to_px(layout_box), layout_box.width(), - layout_box.box_model().padding().right.to_px(), - layout_box.box_model().border().right.to_px(), - layout_box.box_model().margin().right.to_px()); + layout_box.box_model().padding().right.to_px(layout_box), + layout_box.box_model().border().right.to_px(layout_box), + layout_box.box_model().margin().right.to_px(layout_box)); // And the vertical box properties dbgprintf(" [%g+%g+%g %g %g+%g+%g]", - layout_box.box_model().margin().top.to_px(), - layout_box.box_model().border().top.to_px(), - layout_box.box_model().padding().top.to_px(), + layout_box.box_model().margin().top.to_px(layout_box), + layout_box.box_model().border().top.to_px(layout_box), + layout_box.box_model().padding().top.to_px(layout_box), layout_box.height(), - layout_box.box_model().padding().bottom.to_px(), - layout_box.box_model().border().bottom.to_px(), - layout_box.box_model().margin().bottom.to_px()); + layout_box.box_model().padding().bottom.to_px(layout_box), + layout_box.box_model().border().bottom.to_px(layout_box), + layout_box.box_model().margin().bottom.to_px(layout_box)); dbgprintf("\n"); } diff --git a/Libraries/LibWeb/Layout/BoxModelMetrics.cpp b/Libraries/LibWeb/Layout/BoxModelMetrics.cpp index b218ce3c7c..c937918eaf 100644 --- a/Libraries/LibWeb/Layout/BoxModelMetrics.cpp +++ b/Libraries/LibWeb/Layout/BoxModelMetrics.cpp @@ -36,13 +36,13 @@ BoxModelMetrics::~BoxModelMetrics() { } -BoxModelMetrics::PixelBox BoxModelMetrics::full_margin() const +BoxModelMetrics::PixelBox BoxModelMetrics::full_margin(const LayoutNode& layout_node) const { return { - m_margin.top.to_px() + m_border.top.to_px() + m_padding.top.to_px(), - m_margin.right.to_px() + m_border.right.to_px() + m_padding.right.to_px(), - m_margin.bottom.to_px() + m_border.bottom.to_px() + m_padding.bottom.to_px(), - m_margin.left.to_px() + m_border.left.to_px() + m_padding.left.to_px(), + m_margin.top.to_px(layout_node) + m_border.top.to_px(layout_node) + m_padding.top.to_px(layout_node), + m_margin.right.to_px(layout_node) + m_border.right.to_px(layout_node) + m_padding.right.to_px(layout_node), + m_margin.bottom.to_px(layout_node) + m_border.bottom.to_px(layout_node) + m_padding.bottom.to_px(layout_node), + m_margin.left.to_px(layout_node) + m_border.left.to_px(layout_node) + m_padding.left.to_px(layout_node), }; } diff --git a/Libraries/LibWeb/Layout/BoxModelMetrics.h b/Libraries/LibWeb/Layout/BoxModelMetrics.h index f32fbff9d7..3a699c0f4a 100644 --- a/Libraries/LibWeb/Layout/BoxModelMetrics.h +++ b/Libraries/LibWeb/Layout/BoxModelMetrics.h @@ -53,7 +53,7 @@ public: float left; }; - PixelBox full_margin() const; + PixelBox full_margin(const LayoutNode&) const; private: LengthBox m_margin; diff --git a/Libraries/LibWeb/Layout/LayoutBlock.cpp b/Libraries/LibWeb/Layout/LayoutBlock.cpp index 39e3fd17c9..e6422ef685 100644 --- a/Libraries/LibWeb/Layout/LayoutBlock.cpp +++ b/Libraries/LibWeb/Layout/LayoutBlock.cpp @@ -86,7 +86,7 @@ void LayoutBlock::layout_block_children(LayoutMode layout_mode) child_block.layout(layout_mode); if (!child_block.is_absolutely_positioned()) - content_height = child_block.rect().bottom() + child_block.box_model().full_margin().bottom - rect().top(); + content_height = child_block.rect().bottom() + child_block.box_model().full_margin(*this).bottom - rect().top(); }); if (layout_mode != LayoutMode::Default) { float max_width = 0; @@ -112,7 +112,7 @@ void LayoutBlock::layout_inline_children(LayoutMode layout_mode) line_box.trim_trailing_whitespace(); } - float min_line_height = style().line_height(); + float min_line_height = style().line_height(*this); float line_spacing = min_line_height - style().font().glyph_height(); float content_height = 0; @@ -221,7 +221,7 @@ void LayoutBlock::compute_width() auto& style = this->style(); auto auto_value = Length(); - auto zero_value = Length(0, Length::Type::Absolute); + auto zero_value = Length(0, Length::Type::Px); Length margin_left; Length margin_right; @@ -247,7 +247,7 @@ void LayoutBlock::compute_width() float total_px = 0; for (auto& value : { margin_left, border_left, padding_left, width, padding_right, border_right, margin_right }) { - total_px += value.to_px(); + total_px += value.to_px(*this); } #ifdef HTML_DEBUG @@ -273,20 +273,20 @@ void LayoutBlock::compute_width() if (margin_right.is_auto()) margin_right = zero_value; if (underflow_px >= 0) { - width = Length(underflow_px, Length::Type::Absolute); + width = Length(underflow_px, Length::Type::Px); } else { width = zero_value; - margin_right = Length(margin_right.to_px() + underflow_px, Length::Type::Absolute); + margin_right = Length(margin_right.to_px(*this) + underflow_px, Length::Type::Px); } } else { if (!margin_left.is_auto() && !margin_right.is_auto()) { - margin_right = Length(margin_right.to_px() + underflow_px, Length::Type::Absolute); + margin_right = Length(margin_right.to_px(*this) + underflow_px, Length::Type::Px); } else if (!margin_left.is_auto() && margin_right.is_auto()) { - margin_right = Length(underflow_px, Length::Type::Absolute); + margin_right = Length(underflow_px, Length::Type::Px); } else if (margin_left.is_auto() && !margin_right.is_auto()) { - margin_left = Length(underflow_px, Length::Type::Absolute); + margin_left = Length(underflow_px, Length::Type::Px); } else { // margin_left.is_auto() && margin_right.is_auto() - auto half_of_the_underflow = Length(underflow_px / 2, Length::Type::Absolute); + auto half_of_the_underflow = Length(underflow_px / 2, Length::Type::Px); margin_left = half_of_the_underflow; margin_right = half_of_the_underflow; } @@ -323,8 +323,8 @@ void LayoutBlock::compute_width() // 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars. float available_width = containing_block.width() - - margin_left.to_px() - border_left.to_px() - padding_left.to_px() - - padding_right.to_px() - border_right.to_px() - margin_right.to_px(); + - margin_left.to_px(*this) - border_left.to_px(*this) - padding_left.to_px(*this) + - padding_right.to_px(*this) - border_right.to_px(*this) - margin_right.to_px(*this); // Calculate the preferred width by formatting the content without breaking lines // other than where explicit line breaks occur. @@ -338,7 +338,7 @@ void LayoutBlock::compute_width() float preferred_minimum_width = greatest_child_width(); // Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width). - width = Length(min(max(preferred_minimum_width, available_width), preferred_width), Length::Type::Absolute); + width = Length(min(max(preferred_minimum_width, available_width), preferred_width), Length::Type::Px); } } @@ -354,7 +354,7 @@ void LayoutBlock::compute_width() // but this time using the computed value of 'max-width' as the computed value for 'width'. auto specified_max_width = style.length_or_fallback(CSS::PropertyID::MaxWidth, auto_value, containing_block.width()); if (!specified_max_width.is_auto()) { - if (used_width.to_px() > specified_max_width.to_px()) { + if (used_width.to_px(*this) > specified_max_width.to_px(*this)) { used_width = try_compute_width(specified_max_width); } } @@ -363,12 +363,12 @@ void LayoutBlock::compute_width() // but this time using the value of 'min-width' as the computed value for 'width'. auto specified_min_width = style.length_or_fallback(CSS::PropertyID::MinWidth, auto_value, containing_block.width()); if (!specified_min_width.is_auto()) { - if (used_width.to_px() < specified_min_width.to_px()) { + if (used_width.to_px(*this) < specified_min_width.to_px(*this)) { used_width = try_compute_width(specified_min_width); } } - rect().set_width(used_width.to_px()); + rect().set_width(used_width.to_px(*this)); box_model().margin().left = margin_left; box_model().margin().right = margin_right; box_model().border().left = border_left; @@ -381,13 +381,10 @@ void LayoutBlock::compute_position() { auto& style = this->style(); - auto auto_value = Length(); - auto zero_value = Length(0, Length::Type::Absolute); + auto zero_value = Length(0, Length::Type::Px); auto& containing_block = *this->containing_block(); - auto width = style.length_or_fallback(CSS::PropertyID::Width, auto_value, containing_block.width()); - if (style.position() == CSS::Position::Absolute) { box_model().offset().top = style.length_or_fallback(CSS::PropertyID::Top, zero_value, containing_block.height()); box_model().offset().right = style.length_or_fallback(CSS::PropertyID::Right, zero_value, containing_block.width()); @@ -402,18 +399,18 @@ void LayoutBlock::compute_position() box_model().padding().top = style.length_or_fallback(CSS::PropertyID::PaddingTop, zero_value, containing_block.width()); box_model().padding().bottom = style.length_or_fallback(CSS::PropertyID::PaddingBottom, zero_value, containing_block.width()); - float position_x = box_model().margin().left.to_px() - + box_model().border().left.to_px() - + box_model().padding().left.to_px() - + box_model().offset().left.to_px(); + float position_x = box_model().margin().left.to_px(*this) + + box_model().border().left.to_px(*this) + + box_model().padding().left.to_px(*this) + + box_model().offset().left.to_px(*this); if (style.position() != CSS::Position::Absolute || containing_block.style().position() == CSS::Position::Absolute) position_x += containing_block.x(); rect().set_x(position_x); - float position_y = box_model().full_margin().top - + box_model().offset().top.to_px(); + float position_y = box_model().full_margin(*this).top + + box_model().offset().top.to_px(*this); if (style.position() != CSS::Position::Absolute || containing_block.style().position() == CSS::Position::Absolute) { LayoutBlock* relevant_sibling = previous_sibling(); @@ -429,7 +426,7 @@ void LayoutBlock::compute_position() auto& previous_sibling_rect = relevant_sibling->rect(); auto& previous_sibling_style = relevant_sibling->box_model(); position_y += previous_sibling_rect.y() + previous_sibling_rect.height(); - position_y += previous_sibling_style.full_margin().bottom; + position_y += previous_sibling_style.full_margin(*this).bottom; } } @@ -441,7 +438,7 @@ void LayoutBlock::compute_height() auto& style = this->style(); auto height = style.length_or_fallback(CSS::PropertyID::Height, Length(), containing_block()->height()); if (height.is_absolute()) - rect().set_height(height.to_px()); + rect().set_height(height.to_px(*this)); } void LayoutBlock::render(RenderingContext& context) diff --git a/Libraries/LibWeb/Layout/LayoutBox.cpp b/Libraries/LibWeb/Layout/LayoutBox.cpp index 27add6241f..5aaefa3fee 100644 --- a/Libraries/LibWeb/Layout/LayoutBox.cpp +++ b/Libraries/LibWeb/Layout/LayoutBox.cpp @@ -43,7 +43,7 @@ void LayoutBox::paint_border(RenderingContext& context, Edge edge, const Gfx::Fl return; auto border_style = style().property(style_property_id); - float width = border_width.value()->to_length().to_px(); + float width = border_width.value()->to_length().to_px(*this); if (width <= 0) return; @@ -143,7 +143,7 @@ void LayoutBox::paint_border(RenderingContext& context, Edge edge, const Gfx::Fl auto width = style().property(property_id); if (!width.has_value()) return 0; - return width.value()->to_length().to_px(); + return width.value()->to_length().to_px(*this); }; float p1_step = 0; @@ -203,10 +203,10 @@ void LayoutBox::render(RenderingContext& context) #endif Gfx::FloatRect padded_rect; - padded_rect.set_x(x() - box_model().padding().left.to_px()); - padded_rect.set_width(width() + box_model().padding().left.to_px() + box_model().padding().right.to_px()); - padded_rect.set_y(y() - box_model().padding().top.to_px()); - padded_rect.set_height(height() + box_model().padding().top.to_px() + box_model().padding().bottom.to_px()); + padded_rect.set_x(x() - box_model().padding().left.to_px(*this)); + padded_rect.set_width(width() + box_model().padding().left.to_px(*this) + box_model().padding().right.to_px(*this)); + padded_rect.set_y(y() - box_model().padding().top.to_px(*this)); + padded_rect.set_height(height() + box_model().padding().top.to_px(*this) + box_model().padding().bottom.to_px(*this)); if (!is_body()) { auto bgcolor = style().property(CSS::PropertyID::BackgroundColor); @@ -224,10 +224,10 @@ void LayoutBox::render(RenderingContext& context) } Gfx::FloatRect bordered_rect; - bordered_rect.set_x(padded_rect.x() - box_model().border().left.to_px()); - bordered_rect.set_width(padded_rect.width() + box_model().border().left.to_px() + box_model().border().right.to_px()); - bordered_rect.set_y(padded_rect.y() - box_model().border().top.to_px()); - bordered_rect.set_height(padded_rect.height() + box_model().border().top.to_px() + box_model().border().bottom.to_px()); + bordered_rect.set_x(padded_rect.x() - box_model().border().left.to_px(*this)); + bordered_rect.set_width(padded_rect.width() + box_model().border().left.to_px(*this) + box_model().border().right.to_px(*this)); + bordered_rect.set_y(padded_rect.y() - box_model().border().top.to_px(*this)); + bordered_rect.set_height(padded_rect.height() + box_model().border().top.to_px(*this) + box_model().border().bottom.to_px(*this)); paint_border(context, Edge::Left, bordered_rect, CSS::PropertyID::BorderLeftStyle, CSS::PropertyID::BorderLeftColor, CSS::PropertyID::BorderLeftWidth); paint_border(context, Edge::Right, bordered_rect, CSS::PropertyID::BorderRightStyle, CSS::PropertyID::BorderRightColor, CSS::PropertyID::BorderRightWidth); diff --git a/Libraries/LibWeb/Layout/LayoutNode.cpp b/Libraries/LibWeb/Layout/LayoutNode.cpp index a9039492fd..e4a21bb3c7 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.cpp +++ b/Libraries/LibWeb/Layout/LayoutNode.cpp @@ -162,6 +162,13 @@ void LayoutNode::set_needs_display() } } +float LayoutNode::font_size() const +{ + // FIXME: This doesn't work right for relative font-sizes + auto length = style().length_or_fallback(CSS::PropertyID::FontSize, Length(10, Length::Type::Px)); + return length.raw_value(); +} + Gfx::FloatPoint LayoutNode::box_type_agnostic_position() const { if (is_box()) diff --git a/Libraries/LibWeb/Layout/LayoutNode.h b/Libraries/LibWeb/Layout/LayoutNode.h index dc46e6019b..adcd160d81 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.h +++ b/Libraries/LibWeb/Layout/LayoutNode.h @@ -158,6 +158,8 @@ public: Gfx::FloatPoint box_type_agnostic_position() const; + float font_size() const; + protected: explicit LayoutNode(const Node*); diff --git a/Libraries/LibWeb/Layout/LayoutReplaced.cpp b/Libraries/LibWeb/Layout/LayoutReplaced.cpp index 1698697b5f..4aa9b5a259 100644 --- a/Libraries/LibWeb/Layout/LayoutReplaced.cpp +++ b/Libraries/LibWeb/Layout/LayoutReplaced.cpp @@ -47,7 +47,7 @@ float LayoutReplaced::calculate_width() const auto& style = this->style(); auto auto_value = Length(); - auto zero_value = Length(0, Length::Type::Absolute); + auto zero_value = Length(0, Length::Type::Px); auto& containing_block = *this->containing_block(); auto margin_left = style.length_or_fallback(CSS::PropertyID::MarginLeft, zero_value, containing_block.width()); @@ -65,7 +65,7 @@ float LayoutReplaced::calculate_width() const // FIXME: Actually compute 'width' auto computed_width = specified_width; - float used_width = specified_width.to_px(); + float used_width = specified_width.to_px(*this); // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, // then that intrinsic width is the used value of 'width'. @@ -100,16 +100,12 @@ float LayoutReplaced::calculate_height() const // 'inline-block' replaced elements in normal flow and floating replaced elements auto& style = this->style(); auto auto_value = Length(); - auto zero_value = Length(0, Length::Type::Absolute); auto& containing_block = *this->containing_block(); - auto margin_top = style.length_or_fallback(CSS::PropertyID::MarginTop, zero_value, containing_block.width()); - auto margin_bottom = style.length_or_fallback(CSS::PropertyID::MarginBottom, zero_value, containing_block.width()); - auto specified_width = style.length_or_fallback(CSS::PropertyID::Width, auto_value, containing_block.width()); auto specified_height = style.length_or_fallback(CSS::PropertyID::Height, auto_value, containing_block.height()); - float used_height = specified_height.to_px(); + float used_height = specified_height.to_px(*this); // If 'height' and 'width' both have computed values of 'auto' and the element also has // an intrinsic height, then that intrinsic height is the used value of 'height'. @@ -128,12 +124,9 @@ float LayoutReplaced::calculate_height() const Gfx::FloatPoint LayoutReplaced::calculate_position() { auto& style = this->style(); - auto auto_value = Length(); - auto zero_value = Length(0, Length::Type::Absolute); + auto zero_value = Length(0, Length::Type::Px); auto& containing_block = *this->containing_block(); - auto width = style.length_or_fallback(CSS::PropertyID::Width, auto_value, containing_block.width()); - if (style.position() == CSS::Position::Absolute) { box_model().offset().top = style.length_or_fallback(CSS::PropertyID::Top, zero_value, containing_block.height()); box_model().offset().right = style.length_or_fallback(CSS::PropertyID::Right, zero_value, containing_block.width()); @@ -148,15 +141,15 @@ Gfx::FloatPoint LayoutReplaced::calculate_position() box_model().padding().top = style.length_or_fallback(CSS::PropertyID::PaddingTop, zero_value, containing_block.width()); box_model().padding().bottom = style.length_or_fallback(CSS::PropertyID::PaddingBottom, zero_value, containing_block.width()); - float position_x = box_model().margin().left.to_px() - + box_model().border().left.to_px() - + box_model().padding().left.to_px() - + box_model().offset().left.to_px(); + float position_x = box_model().margin().left.to_px(*this) + + box_model().border().left.to_px(*this) + + box_model().padding().left.to_px(*this) + + box_model().offset().left.to_px(*this); if (style.position() != CSS::Position::Absolute || containing_block.style().position() == CSS::Position::Absolute) position_x += containing_block.x(); - float position_y = box_model().full_margin().top + box_model().offset().top.to_px(); + float position_y = box_model().full_margin(*this).top + box_model().offset().top.to_px(*this); return { position_x, position_y }; } diff --git a/Libraries/LibWeb/Parser/CSSParser.cpp b/Libraries/LibWeb/Parser/CSSParser.cpp index 0ba115e7e9..507ff8320d 100644 --- a/Libraries/LibWeb/Parser/CSSParser.cpp +++ b/Libraries/LibWeb/Parser/CSSParser.cpp @@ -253,6 +253,10 @@ static Optional<float> parse_number(const StringView& view) // FIXME: Maybe we should have "ends_with_ignoring_case()" ? if (view.to_string().to_lowercase().ends_with("px")) return parse_number(view.substring_view(0, view.length() - 2)); + if (view.to_string().to_lowercase().ends_with("rem")) + return parse_number(view.substring_view(0, view.length() - 3)); + if (view.to_string().to_lowercase().ends_with("em")) + return parse_number(view.substring_view(0, view.length() - 2)); return try_parse_float(view); } @@ -263,7 +267,11 @@ NonnullRefPtr<StyleValue> parse_css_value(const StringView& string) if (number.has_value()) { if (string.ends_with('%')) return PercentageStyleValue::create(number.value()); - return LengthStyleValue::create(Length(number.value(), Length::Type::Absolute)); + if (string.ends_with("em")) + return LengthStyleValue::create(Length(number.value(), Length::Type::Em)); + if (string.ends_with("rem")) + return LengthStyleValue::create(Length(number.value(), Length::Type::Rem)); + return LengthStyleValue::create(Length(number.value(), Length::Type::Px)); } if (string.equals_ignoring_case("inherit")) |