summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Libraries/LibWeb/Layout/InlineFormattingContext.cpp6
-rw-r--r--Libraries/LibWeb/Layout/InlineNode.cpp28
-rw-r--r--Libraries/LibWeb/Layout/InlineNode.h4
-rw-r--r--Libraries/LibWeb/Layout/LineBox.cpp4
-rw-r--r--Libraries/LibWeb/Layout/LineBox.h2
-rw-r--r--Libraries/LibWeb/Layout/LineBoxFragment.cpp4
-rw-r--r--Libraries/LibWeb/Layout/LineBoxFragment.h12
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 };
};
}