Skip to content

Commit

Permalink
LibWeb: Add border box top/bottom metrics to line box fragments
Browse files Browse the repository at this point in the history
This will allow us to support more kinds of vertical alignment.
  • Loading branch information
awesomekling committed Feb 26, 2022
1 parent 8b369bf commit 797f51e
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 10 deletions.
8 changes: 6 additions & 2 deletions Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,12 @@ float FormattingContext::compute_auto_height_for_block_level_element(FormattingS
top = 0;
if (!line_boxes.is_empty()) {
for (auto& fragment : line_boxes.last().fragments()) {
if (!bottom.has_value() || (fragment.offset().y() + fragment.height()) > bottom.value())
bottom = fragment.offset().y() + fragment.height();
float fragment_top = fragment.offset().y() - fragment.border_box_top();
if (!top.has_value() || fragment_top < *top)
top = fragment_top;
float fragment_bottom = fragment.offset().y() + fragment.height() + fragment.border_box_bottom();
if (!bottom.has_value() || fragment_bottom > *bottom)
bottom = fragment_bottom;
}
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void InlineFormattingContext::run(Box const&, LayoutMode layout_mode)
for (auto& line_box : m_state.get(containing_block()).line_boxes) {
float max_height = min_line_height;
for (auto& fragment : line_box.fragments()) {
max_height = max(max_height, fragment.height());
max_height = max(max_height, fragment.border_box_height());
}
max_line_width = max(max_line_width, line_box.width());
content_height += max_height;
Expand Down
4 changes: 2 additions & 2 deletions Userland/Libraries/LibWeb/Layout/LineBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

namespace Web::Layout {

void LineBox::add_fragment(Node const& layout_node, int start, int length, float leading_size, float trailing_size, float content_width, float content_height, LineBoxFragment::Type fragment_type)
void LineBox::add_fragment(Node const& layout_node, int start, int length, float leading_size, float trailing_size, float content_width, float content_height, float border_box_top, float border_box_bottom, LineBoxFragment::Type fragment_type)
{
bool text_align_is_justify = layout_node.computed_values().text_align() == CSS::TextAlign::Justify;
if (!text_align_is_justify && !m_fragments.is_empty() && &m_fragments.last().layout_node() == &layout_node) {
Expand All @@ -24,7 +24,7 @@ void LineBox::add_fragment(Node const& layout_node, int start, int length, float
m_fragments.last().m_length = (start - m_fragments.last().m_start) + length;
m_fragments.last().set_width(m_fragments.last().width() + content_width);
} else {
m_fragments.append(make<LineBoxFragment>(layout_node, start, length, Gfx::FloatPoint(m_width + leading_size, 0.0f), Gfx::FloatSize(content_width, content_height), fragment_type));
m_fragments.append(make<LineBoxFragment>(layout_node, start, length, Gfx::FloatPoint(m_width + leading_size, 0.0f), Gfx::FloatSize(content_width, content_height), border_box_top, border_box_bottom, fragment_type));
}
m_width += content_width + leading_size + trailing_size;

Expand Down
2 changes: 1 addition & 1 deletion Userland/Libraries/LibWeb/Layout/LineBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class LineBox {

float width() const { return m_width; }

void add_fragment(Node const& layout_node, int start, int length, float leading_size, float trailing_size, float content_width, float content_height, LineBoxFragment::Type = LineBoxFragment::Type::Normal);
void add_fragment(Node const& layout_node, int start, int length, float leading_size, float trailing_size, float content_width, float content_height, float border_box_top, float border_box_bottom, LineBoxFragment::Type = LineBoxFragment::Type::Normal);

const NonnullOwnPtrVector<LineBoxFragment>& fragments() const { return m_fragments; }
NonnullOwnPtrVector<LineBoxFragment>& fragments() { return m_fragments; }
Expand Down
10 changes: 9 additions & 1 deletion Userland/Libraries/LibWeb/Layout/LineBoxFragment.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ class LineBoxFragment : public Weakable<LineBoxFragment> {
Trailing,
};

LineBoxFragment(Node const& layout_node, int start, int length, const Gfx::FloatPoint& offset, const Gfx::FloatSize& size, Type type)
LineBoxFragment(Node const& layout_node, int start, int length, Gfx::FloatPoint const& offset, Gfx::FloatSize const& size, float border_box_top, float border_box_bottom, Type type)
: m_layout_node(layout_node)
, m_start(start)
, m_length(length)
, m_offset(offset)
, m_size(size)
, m_border_box_top(border_box_top)
, m_border_box_bottom(border_box_bottom)
, m_type(type)
{
}
Expand All @@ -48,6 +50,10 @@ class LineBoxFragment : public Weakable<LineBoxFragment> {
float width() const { return m_size.width(); }
float height() const { return m_size.height(); }

float border_box_height() const { return m_border_box_top + height() + m_border_box_bottom; }
float border_box_top() const { return m_border_box_top; }
float border_box_bottom() const { return m_border_box_bottom; }

float absolute_x() const { return absolute_rect().x(); }

void paint(PaintContext&, PaintPhase);
Expand All @@ -66,6 +72,8 @@ class LineBoxFragment : public Weakable<LineBoxFragment> {
int m_length { 0 };
Gfx::FloatPoint m_offset;
Gfx::FloatSize m_size;
float m_border_box_top { 0 };
float m_border_box_bottom { 0 };
Type m_type { Type::Normal };
};

Expand Down
6 changes: 3 additions & 3 deletions Userland/Libraries/LibWeb/Layout/LineBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ LineBox& LineBuilder::ensure_last_line_box()
void LineBuilder::append_box(Box const& box, float leading_size, float trailing_size)
{
auto const& box_state = m_formatting_state.get(box);
ensure_last_line_box().add_fragment(box, 0, 0, leading_size, trailing_size, box_state.content_width, box_state.content_height);
ensure_last_line_box().add_fragment(box, 0, 0, leading_size, trailing_size, box_state.content_width, box_state.content_height, box_state.border_box_top(), box_state.border_box_bottom());
m_max_height_on_current_line = max(m_max_height_on_current_line, box_state.content_height);
}

void LineBuilder::append_text_chunk(TextNode const& text_node, size_t offset_in_node, size_t length_in_node, float leading_size, float trailing_size, float content_width, float content_height)
{
ensure_last_line_box().add_fragment(text_node, offset_in_node, length_in_node, leading_size, trailing_size, content_width, content_height);
ensure_last_line_box().add_fragment(text_node, offset_in_node, length_in_node, leading_size, trailing_size, content_width, content_height, 0, 0);
m_max_height_on_current_line = max(m_max_height_on_current_line, content_height);
}

Expand Down Expand Up @@ -127,7 +127,7 @@ void LineBuilder::update_last_line()
for (auto& fragment : line_box.fragments()) {
float fragment_baseline;
if (fragment.layout_node().is_box()) {
fragment_baseline = m_formatting_state.get(static_cast<Box const&>(fragment.layout_node())).content_height;
fragment_baseline = m_formatting_state.get(static_cast<Box const&>(fragment.layout_node())).border_box_height();
} else {
float font_baseline = fragment.layout_node().font().baseline();
fragment_baseline = (max_height / 2.0f) + (font_baseline / 2.0f);
Expand Down

0 comments on commit 797f51e

Please sign in to comment.