diff options
-rw-r--r-- | Libraries/LibWeb/Layout/InlineFormattingContext.cpp | 6 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/InlineNode.cpp | 28 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/InlineNode.h | 4 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LineBox.cpp | 4 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LineBox.h | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LineBoxFragment.cpp | 4 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LineBoxFragment.h | 12 |
7 files changed, 56 insertions, 4 deletions
diff --git a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 19f3b77d44..029ade00a0 100644 --- a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -112,6 +112,12 @@ void InlineFormattingContext::run(LayoutMode layout_mode) for (size_t i = 0; i < line_box.fragments().size(); ++i) { auto& fragment = line_box.fragments()[i]; + if (fragment.type() == LineBoxFragment::Type::Leading || fragment.type() == LineBoxFragment::Type::Trailing) { + fragment.set_height(max_height); + } else { + fragment.set_height(max(min_line_height, fragment.height())); + } + // Vertically align everyone's bottom to the line. // FIXME: Support other kinds of vertical alignment. fragment.set_offset({ roundf(x_offset + fragment.offset().x()), content_height + (max_height - fragment.height()) - (line_spacing / 2) }); diff --git a/Libraries/LibWeb/Layout/InlineNode.cpp b/Libraries/LibWeb/Layout/InlineNode.cpp index 8abfd4cab0..17f41e6b22 100644 --- a/Libraries/LibWeb/Layout/InlineNode.cpp +++ b/Libraries/LibWeb/Layout/InlineNode.cpp @@ -24,7 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <LibGfx/Painter.h> #include <LibWeb/DOM/Element.h> +#include <LibWeb/Layout/BlockBox.h> #include <LibWeb/Layout/InlineNode.h> namespace Web::Layout { @@ -39,4 +41,30 @@ InlineNode::~InlineNode() { } +void InlineNode::split_into_lines(BlockBox& containing_block, LayoutMode layout_mode) +{ + if (!style().padding().left.is_undefined_or_auto()) { + float padding_left = style().padding().left.resolved(CSS::Length::make_px(0), *this, containing_block.width()).to_px(*this); + containing_block.ensure_last_line_box().add_fragment(*this, 0, 0, padding_left, 0, LineBoxFragment::Type::Leading); + } + + Node::split_into_lines(containing_block, layout_mode); + + if (!style().padding().right.is_undefined_or_auto()) { + float padding_right = style().padding().right.resolved(CSS::Length::make_px(0), *this, containing_block.width()).to_px(*this); + containing_block.ensure_last_line_box().add_fragment(*this, 0, 0, padding_right, 0, LineBoxFragment::Type::Trailing); + } +} + +void InlineNode::paint_fragment(PaintContext& context, const LineBoxFragment& fragment, PaintPhase phase) const +{ + auto& painter = context.painter(); + + if (phase == PaintPhase::Background) { + auto background_color = specified_style().property(CSS::PropertyID::BackgroundColor); + if (background_color.has_value() && background_color.value()->is_color()) + painter.fill_rect(enclosing_int_rect(fragment.absolute_rect()), background_color.value()->to_color(document())); + } +} + } diff --git a/Libraries/LibWeb/Layout/InlineNode.h b/Libraries/LibWeb/Layout/InlineNode.h index 004e8b81c5..91a74a9caa 100644 --- a/Libraries/LibWeb/Layout/InlineNode.h +++ b/Libraries/LibWeb/Layout/InlineNode.h @@ -36,6 +36,10 @@ public: virtual ~InlineNode() override; virtual const char* class_name() const override { return "InlineNode"; } + void paint_fragment(PaintContext&, const LineBoxFragment&, PaintPhase) const; + + virtual void split_into_lines(BlockBox& containing_block, LayoutMode) override; + private: virtual bool is_inline_node() const final { return true; } }; diff --git a/Libraries/LibWeb/Layout/LineBox.cpp b/Libraries/LibWeb/Layout/LineBox.cpp index 99cc777fcb..6ef3efbfa5 100644 --- a/Libraries/LibWeb/Layout/LineBox.cpp +++ b/Libraries/LibWeb/Layout/LineBox.cpp @@ -33,7 +33,7 @@ namespace Web::Layout { -void LineBox::add_fragment(const Node& layout_node, int start, int length, int width, int height) +void LineBox::add_fragment(const Node& layout_node, int start, int length, int width, int height, LineBoxFragment::Type fragment_type) { bool text_align_is_justify = layout_node.style().text_align() == CSS::TextAlign::Justify; if (!text_align_is_justify && !m_fragments.is_empty() && &m_fragments.last().layout_node() == &layout_node) { @@ -42,7 +42,7 @@ void LineBox::add_fragment(const Node& layout_node, int start, int length, int w m_fragments.last().m_length = (start - m_fragments.last().m_start) + length; m_fragments.last().set_width(m_fragments.last().width() + width); } else { - m_fragments.append(make<LineBoxFragment>(layout_node, start, length, Gfx::FloatPoint(m_width, 0.0f), Gfx::FloatSize(width, height))); + m_fragments.append(make<LineBoxFragment>(layout_node, start, length, Gfx::FloatPoint(m_width, 0.0f), Gfx::FloatSize(width, height), fragment_type)); } m_width += width; diff --git a/Libraries/LibWeb/Layout/LineBox.h b/Libraries/LibWeb/Layout/LineBox.h index 242adf0007..4198f34ddc 100644 --- a/Libraries/LibWeb/Layout/LineBox.h +++ b/Libraries/LibWeb/Layout/LineBox.h @@ -38,7 +38,7 @@ public: float width() const { return m_width; } - void add_fragment(const Node& layout_node, int start, int length, int width, int height); + void add_fragment(const Node& layout_node, int start, int length, int width, int height, LineBoxFragment::Type = LineBoxFragment::Type::Normal); const NonnullOwnPtrVector<LineBoxFragment>& fragments() const { return m_fragments; } NonnullOwnPtrVector<LineBoxFragment>& fragments() { return m_fragments; } diff --git a/Libraries/LibWeb/Layout/LineBoxFragment.cpp b/Libraries/LibWeb/Layout/LineBoxFragment.cpp index 4918f56789..8e589469ff 100644 --- a/Libraries/LibWeb/Layout/LineBoxFragment.cpp +++ b/Libraries/LibWeb/Layout/LineBoxFragment.cpp @@ -29,6 +29,7 @@ #include <LibWeb/Layout/InitialContainingBlockBox.h> #include <LibWeb/Layout/LineBoxFragment.h> #include <LibWeb/Layout/TextNode.h> +#include <LibWeb/Layout/InlineNode.h> #include <LibWeb/Painting/PaintContext.h> #include <ctype.h> @@ -41,6 +42,9 @@ void LineBoxFragment::paint(PaintContext& context, PaintPhase phase) return; } + if (is<InlineNode>(layout_node())) + downcast<InlineNode>(layout_node()).paint_fragment(context, *this, phase); + if (is<TextNode>(layout_node())) downcast<TextNode>(layout_node()).paint_fragment(context, *this, phase); } diff --git a/Libraries/LibWeb/Layout/LineBoxFragment.h b/Libraries/LibWeb/Layout/LineBoxFragment.h index 5e91dff564..39fc97972e 100644 --- a/Libraries/LibWeb/Layout/LineBoxFragment.h +++ b/Libraries/LibWeb/Layout/LineBoxFragment.h @@ -37,12 +37,19 @@ class LineBoxFragment : public Weakable<LineBoxFragment> { friend class LineBox; public: - LineBoxFragment(const Node& layout_node, int start, int length, const Gfx::FloatPoint& offset, const Gfx::FloatSize& size) + enum class Type { + Normal, + Leading, + Trailing, + }; + + LineBoxFragment(const Node& layout_node, int start, int length, const Gfx::FloatPoint& offset, const Gfx::FloatSize& size, Type type) : m_layout_node(layout_node) , m_start(start) , m_length(length) , m_offset(offset) , m_size(size) + , m_type(type) { } @@ -50,12 +57,14 @@ public: int start() const { return m_start; } int length() const { return m_length; } const Gfx::FloatRect absolute_rect() const; + Type type() const { return m_type; } const Gfx::FloatPoint& offset() const { return m_offset; } void set_offset(const Gfx::FloatPoint& offset) { m_offset = offset; } const Gfx::FloatSize& size() const { return m_size; } void set_width(float width) { m_size.set_width(width); } + void set_height(float height) { m_size.set_height(height); } float width() const { return m_size.width(); } float height() const { return m_size.height(); } @@ -77,6 +86,7 @@ private: int m_length { 0 }; Gfx::FloatPoint m_offset; Gfx::FloatSize m_size; + Type m_type { Type::Normal }; }; } |