mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:07:36 +00:00
LibWeb: Support inline-level padding and border properly
Here's roughly how this works: - InlineLevelIterator keeps a nesting stack of inline-level nodes with box model metrics. - When entering a node with box model metrics, we add them to the current "leading metrics". - When exiting a node with box model metrics, we add them to the current "trailing metrics". - Pending leading metrics are consumed by the first fragment added to the line. - Pending trailing metrics are consumed by the last fragment added to the line. Like before, the position of a line box fragment is the top left of its content box. However, fragments are placed horizontally along the line with space inserted for padding and border. InlineNode::paint() now expands the content rect as appropriate when painting background and borders. Note that margins and margin collapsing is not yet implemented. This makes the eyes on ACID2 horizontally centered. :^)
This commit is contained in:
parent
7d2a49eeb8
commit
f2a917229a
8 changed files with 191 additions and 36 deletions
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <LibWeb/Layout/BlockContainer.h>
|
||||
#include <LibWeb/Layout/InlineNode.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
|
||||
namespace Web::Layout {
|
||||
|
@ -31,36 +32,66 @@ public:
|
|||
size_t offset_in_node { 0 };
|
||||
size_t length_in_node { 0 };
|
||||
float width { 0.0f };
|
||||
float padding_start { 0.0f };
|
||||
float padding_end { 0.0f };
|
||||
float border_start { 0.0f };
|
||||
float border_end { 0.0f };
|
||||
float margin_start { 0.0f };
|
||||
float margin_end { 0.0f };
|
||||
bool should_force_break { false };
|
||||
bool is_collapsible_whitespace { false };
|
||||
|
||||
float border_box_width() const
|
||||
{
|
||||
return border_start + padding_start + width + padding_end + border_end;
|
||||
}
|
||||
};
|
||||
|
||||
explicit InlineLevelIterator(Layout::BlockContainer& container, LayoutMode layout_mode)
|
||||
: m_container(container)
|
||||
, m_current_node(container.first_child())
|
||||
, m_layout_mode(layout_mode)
|
||||
{
|
||||
}
|
||||
InlineLevelIterator(Layout::InlineFormattingContext&, Layout::BlockContainer&, LayoutMode);
|
||||
|
||||
Optional<Item> next(float available_width);
|
||||
|
||||
private:
|
||||
void skip_to_next();
|
||||
void compute_next();
|
||||
|
||||
void enter_text_node(Layout::TextNode&, bool previous_is_empty_or_ends_in_whitespace);
|
||||
|
||||
void enter_node_with_box_model_metrics(Layout::NodeWithStyleAndBoxModelMetrics&);
|
||||
void exit_node_with_box_model_metrics();
|
||||
|
||||
void add_extra_box_model_metrics_to_item(Item&, bool add_leading_metrics, bool add_trailing_metrics);
|
||||
|
||||
Layout::Node* next_inline_node_in_pre_order(Layout::Node& current, Layout::Node const* stay_within);
|
||||
|
||||
Layout::InlineFormattingContext& m_inline_formatting_context;
|
||||
Layout::BlockContainer& m_container;
|
||||
Layout::Node* m_current_node { nullptr };
|
||||
Layout::Node* m_next_node { nullptr };
|
||||
LayoutMode const m_layout_mode;
|
||||
|
||||
struct TextNodeContext {
|
||||
bool do_collapse {};
|
||||
bool do_wrap_lines {};
|
||||
bool do_respect_linebreaks {};
|
||||
bool is_first_chunk {};
|
||||
bool is_last_chunk {};
|
||||
TextNode::ChunkIterator chunk_iterator;
|
||||
Optional<TextNode::Chunk> next_chunk {};
|
||||
};
|
||||
|
||||
Optional<TextNodeContext> m_text_node_context;
|
||||
|
||||
struct ExtraBoxMetrics {
|
||||
float margin { 0 };
|
||||
float border { 0 };
|
||||
float padding { 0 };
|
||||
};
|
||||
|
||||
Optional<ExtraBoxMetrics> m_extra_leading_metrics;
|
||||
Optional<ExtraBoxMetrics> m_extra_trailing_metrics;
|
||||
|
||||
Vector<NodeWithStyleAndBoxModelMetrics&> m_box_model_node_stack;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue