diff --git a/Libraries/LibHTML/Layout/LayoutBox.cpp b/Libraries/LibHTML/Layout/LayoutBox.cpp
index 57b91a03bf..b0ecabe3fa 100644
--- a/Libraries/LibHTML/Layout/LayoutBox.cpp
+++ b/Libraries/LibHTML/Layout/LayoutBox.cpp
@@ -8,7 +8,7 @@
//#define DRAW_BOXES_AROUND_LAYOUT_NODES
//#define DRAW_BOXES_AROUND_HOVERED_NODES
-void LayoutBox::paint_border(RenderingContext& context, Edge edge, const Rect& rect, CSS::PropertyID style_property_id, CSS::PropertyID color_property_id, CSS::PropertyID width_property_id)
+void LayoutBox::paint_border(RenderingContext& context, Edge edge, const FloatRect& rect, CSS::PropertyID style_property_id, CSS::PropertyID color_property_id, CSS::PropertyID width_property_id)
{
auto border_width = style().property(width_property_id);
if (!border_width.has_value())
@@ -17,6 +17,8 @@ void LayoutBox::paint_border(RenderingContext& context, Edge edge, const Rect& r
auto border_style = style().property(style_property_id);
float width = border_width.value()->to_length().to_px();
+ int int_width = max((int)width, 1);
+
Color color;
auto border_color = style().property(color_property_id);
if (border_color.has_value()) {
@@ -31,7 +33,7 @@ void LayoutBox::paint_border(RenderingContext& context, Edge edge, const Rect& r
color = Color::Black;
}
- auto first_point_for_edge = [](Edge edge, const Rect& rect) {
+ auto first_point_for_edge = [](Edge edge, const FloatRect& rect) {
switch (edge) {
case Edge::Top:
return rect.top_left();
@@ -45,7 +47,7 @@ void LayoutBox::paint_border(RenderingContext& context, Edge edge, const Rect& r
}
};
- auto second_point_for_edge = [](Edge edge, const Rect& rect) {
+ auto second_point_for_edge = [](Edge edge, const FloatRect& rect) {
switch (edge) {
case Edge::Top:
return rect.top_right();
@@ -73,8 +75,59 @@ void LayoutBox::paint_border(RenderingContext& context, Edge edge, const Rect& r
} else {
// border-style: solid
}
- dbg() << "draw_line(" << p1 << ", " << p2 << ", " << color.to_string() << ", " << (int)width << ")";
- context.painter().draw_line(p1, p2, color, width);
+
+ auto draw_line = [&](auto& p1, auto& p2) {
+ context.painter().draw_line({ (int)p1.x(), (int)p1.y() }, { (int)p2.x(), (int)p2.y() }, color, 1);
+ };
+
+ auto width_for = [&](CSS::PropertyID property_id) -> float {
+ auto width = style().property(property_id);
+ if (!width.has_value())
+ return 0;
+ return width.value()->to_length().to_px();
+ };
+
+ float p1_step = 0;
+ float p2_step = 0;
+
+ switch (edge) {
+ case Edge::Top:
+ p1_step = width_for(CSS::PropertyID::BorderLeftWidth) / (float)int_width;
+ p2_step = width_for(CSS::PropertyID::BorderRightWidth) / (float)int_width;
+ for (int i = 0; i < int_width; ++i) {
+ draw_line(p1, p2);
+ p1.move_by(p1_step, 1);
+ p2.move_by(-p2_step, 1);
+ }
+ break;
+ case Edge::Right:
+ p1_step = width_for(CSS::PropertyID::BorderTopWidth) / (float)int_width;
+ p2_step = width_for(CSS::PropertyID::BorderBottomWidth) / (float)int_width;
+ for (int i = int_width - 1; i >= 0; --i) {
+ draw_line(p1, p2);
+ p1.move_by(-1, p1_step);
+ p2.move_by(-1, -p2_step);
+ }
+ break;
+ case Edge::Bottom:
+ p1_step = width_for(CSS::PropertyID::BorderLeftWidth) / (float)int_width;
+ p2_step = width_for(CSS::PropertyID::BorderRightWidth) / (float)int_width;
+ for (int i = int_width - 1; i >= 0; --i) {
+ draw_line(p1, p2);
+ p1.move_by(p1_step, -1);
+ p2.move_by(-p2_step, -1);
+ }
+ break;
+ case Edge::Left:
+ p1_step = width_for(CSS::PropertyID::BorderTopWidth) / (float)int_width;
+ p2_step = width_for(CSS::PropertyID::BorderBottomWidth) / (float)int_width;
+ for (int i = 0; i < int_width; ++i) {
+ draw_line(p1, p2);
+ p1.move_by(1, p1_step);
+ p2.move_by(1, -p2_step);
+ }
+ break;
+ }
}
void LayoutBox::render(RenderingContext& context)
@@ -93,7 +146,7 @@ void LayoutBox::render(RenderingContext& context)
if (node() && document().inspected_node() == node())
context.painter().draw_rect(enclosing_int_rect(m_rect), Color::Magenta);
- Rect padded_rect;
+ 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());
@@ -102,28 +155,28 @@ void LayoutBox::render(RenderingContext& context)
if (!is_body()) {
auto bgcolor = style().property(CSS::PropertyID::BackgroundColor);
if (bgcolor.has_value() && bgcolor.value()->is_color()) {
- context.painter().fill_rect(padded_rect, bgcolor.value()->to_color(document()));
+ context.painter().fill_rect(enclosing_int_rect(padded_rect), bgcolor.value()->to_color(document()));
}
auto bgimage = style().property(CSS::PropertyID::BackgroundImage);
if (bgimage.has_value() && bgimage.value()->is_image()) {
auto& image_value = static_cast(*bgimage.value());
if (image_value.bitmap()) {
- context.painter().draw_tiled_bitmap(padded_rect, *image_value.bitmap());
+ context.painter().draw_tiled_bitmap(enclosing_int_rect(padded_rect), *image_value.bitmap());
}
}
}
- Rect bordered_rect;
+ 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());
- paint_border(context, Edge::Top, bordered_rect, CSS::PropertyID::BorderTopStyle, CSS::PropertyID::BorderTopColor, CSS::PropertyID::BorderTopWidth);
- paint_border(context, Edge::Right, bordered_rect, CSS::PropertyID::BorderRightStyle, CSS::PropertyID::BorderRightColor, CSS::PropertyID::BorderRightWidth);
- paint_border(context, Edge::Bottom, bordered_rect, CSS::PropertyID::BorderBottomStyle, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomWidth);
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);
+ paint_border(context, Edge::Top, bordered_rect, CSS::PropertyID::BorderTopStyle, CSS::PropertyID::BorderTopColor, CSS::PropertyID::BorderTopWidth);
+ paint_border(context, Edge::Bottom, bordered_rect, CSS::PropertyID::BorderBottomStyle, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomWidth);
LayoutNodeWithStyleAndBoxModelMetrics::render(context);
}
diff --git a/Libraries/LibHTML/Layout/LayoutBox.h b/Libraries/LibHTML/Layout/LayoutBox.h
index 7183d3197d..57adf8b78d 100644
--- a/Libraries/LibHTML/Layout/LayoutBox.h
+++ b/Libraries/LibHTML/Layout/LayoutBox.h
@@ -38,7 +38,7 @@ private:
Bottom,
Left,
};
- void paint_border(RenderingContext&, Edge, const Rect&, CSS::PropertyID style_property_id, CSS::PropertyID color_property_id, CSS::PropertyID width_property_id);
+ void paint_border(RenderingContext&, Edge, const FloatRect&, CSS::PropertyID style_property_id, CSS::PropertyID color_property_id, CSS::PropertyID width_property_id);
FloatRect m_rect;
};