summaryrefslogtreecommitdiff
path: root/Libraries/LibHTML/Layout
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-11-25 13:17:14 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-11-25 13:17:14 +0100
commit05b1ecf1b151889ea44796eb45bfef25714a4973 (patch)
tree0dc230545069b5bd90ea77dd06a7a7b674485810 /Libraries/LibHTML/Layout
parent3c8a1ea386fd8b4b2e2419047adc2a543fb28619 (diff)
downloadserenity-05b1ecf1b151889ea44796eb45bfef25714a4973.zip
LibHTML: Draw each CSS border edge separately with their own style
The borders still look very wrong with any border-width other than 1, but at least we can see that they have the right color, and end up in mostly the right place :^)
Diffstat (limited to 'Libraries/LibHTML/Layout')
-rw-r--r--Libraries/LibHTML/Layout/LayoutBox.cpp122
-rw-r--r--Libraries/LibHTML/Layout/LayoutBox.h8
2 files changed, 86 insertions, 44 deletions
diff --git a/Libraries/LibHTML/Layout/LayoutBox.cpp b/Libraries/LibHTML/Layout/LayoutBox.cpp
index 8e06a5cce1..57b91a03bf 100644
--- a/Libraries/LibHTML/Layout/LayoutBox.cpp
+++ b/Libraries/LibHTML/Layout/LayoutBox.cpp
@@ -8,6 +8,75 @@
//#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)
+{
+ auto border_width = style().property(width_property_id);
+ if (!border_width.has_value())
+ return;
+
+ auto border_style = style().property(style_property_id);
+ float width = border_width.value()->to_length().to_px();
+
+ Color color;
+ auto border_color = style().property(color_property_id);
+ if (border_color.has_value()) {
+ color = border_color.value()->to_color(document());
+ } else {
+ // FIXME: This is basically CSS "currentColor" which should be handled elsewhere
+ // in a much more reusable way.
+ auto current_color = style().property(CSS::PropertyID::Color);
+ if (current_color.has_value())
+ color = current_color.value()->to_color(document());
+ else
+ color = Color::Black;
+ }
+
+ auto first_point_for_edge = [](Edge edge, const Rect& rect) {
+ switch (edge) {
+ case Edge::Top:
+ return rect.top_left();
+ case Edge::Right:
+ return rect.top_right();
+ case Edge::Bottom:
+ return rect.bottom_left();
+ case Edge::Left:
+ default:
+ return rect.top_left();
+ }
+ };
+
+ auto second_point_for_edge = [](Edge edge, const Rect& rect) {
+ switch (edge) {
+ case Edge::Top:
+ return rect.top_right();
+ case Edge::Right:
+ return rect.bottom_right();
+ case Edge::Bottom:
+ return rect.bottom_right();
+ case Edge::Left:
+ default:
+ return rect.bottom_left();
+ }
+ };
+
+ auto p1 = first_point_for_edge(edge, rect);
+ auto p2 = second_point_for_edge(edge, rect);
+
+ if (border_style.has_value() && border_style.value()->to_string() == "inset") {
+ auto top_left_color = Color::from_rgb(0x5a5a5a);
+ auto bottom_right_color = Color::from_rgb(0x888888);
+ color = (edge == Edge::Left || edge == Edge::Top) ? top_left_color : bottom_right_color;
+ } else if (border_style.has_value() && border_style.value()->to_string() == "outset") {
+ auto top_left_color = Color::from_rgb(0x888888);
+ auto bottom_right_color = Color::from_rgb(0x5a5a5a);
+ color = (edge == Edge::Left || edge == Edge::Top) ? top_left_color : bottom_right_color;
+ } else {
+ // border-style: solid
+ }
+ dbg() << "draw_line(" << p1 << ", " << p2 << ", " << color.to_string() << ", " << (int)width << ")";
+ context.painter().draw_line(p1, p2, color, width);
+}
+
void LayoutBox::render(RenderingContext& context)
{
if (!is_visible())
@@ -45,51 +114,16 @@ void LayoutBox::render(RenderingContext& context)
}
}
- // FIXME: Respect all individual border sides
- auto border_width_value = style().property(CSS::PropertyID::BorderTopWidth);
- auto border_color_value = style().property(CSS::PropertyID::BorderTopColor);
- auto border_style_value = style().property(CSS::PropertyID::BorderTopStyle);
-
- if (border_width_value.has_value()) {
- float border_width = border_width_value.value()->to_length().to_px();
-
- Color border_color;
- if (border_color_value.has_value())
- border_color = border_color_value.value()->to_color(document());
- else {
- // FIXME: This is basically CSS "currentColor" which should be handled elsewhere
- // in a much more reusable way.
- auto color_value = style().property(CSS::PropertyID::Color);
- if (color_value.has_value())
- border_color = color_value.value()->to_color(document());
- else
- border_color = Color::Black;
- }
+ Rect 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());
- if (border_style_value.has_value() && border_style_value.value()->to_string() == "inset") {
- // border-style: inset
- auto shadow_color = Color::from_rgb(0x888888);
- auto highlight_color = Color::from_rgb(0x5a5a5a);
- context.painter().draw_line(padded_rect.top_left(), padded_rect.top_right(), highlight_color, border_width);
- context.painter().draw_line(padded_rect.top_right(), padded_rect.bottom_right(), shadow_color, border_width);
- context.painter().draw_line(padded_rect.bottom_right(), padded_rect.bottom_left(), shadow_color, border_width);
- context.painter().draw_line(padded_rect.bottom_left(), padded_rect.top_left(), highlight_color, border_width);
- } else if (border_style_value.has_value() && border_style_value.value()->to_string() == "outset") {
- // border-style: outset
- auto highlight_color = Color::from_rgb(0x888888);
- auto shadow_color = Color::from_rgb(0x5a5a5a);
- context.painter().draw_line(padded_rect.top_left(), padded_rect.top_right(), highlight_color, border_width);
- context.painter().draw_line(padded_rect.top_right(), padded_rect.bottom_right(), shadow_color, border_width);
- context.painter().draw_line(padded_rect.bottom_right(), padded_rect.bottom_left(), shadow_color, border_width);
- context.painter().draw_line(padded_rect.bottom_left(), padded_rect.top_left(), highlight_color, border_width);
- } else {
- // border-style: solid
- context.painter().draw_line(padded_rect.top_left(), padded_rect.top_right(), border_color, border_width);
- context.painter().draw_line(padded_rect.top_right(), padded_rect.bottom_right(), border_color, border_width);
- context.painter().draw_line(padded_rect.bottom_right(), padded_rect.bottom_left(), border_color, border_width);
- context.painter().draw_line(padded_rect.bottom_left(), padded_rect.top_left(), border_color, border_width);
- }
- }
+ 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);
LayoutNodeWithStyleAndBoxModelMetrics::render(context);
}
diff --git a/Libraries/LibHTML/Layout/LayoutBox.h b/Libraries/LibHTML/Layout/LayoutBox.h
index f4d0a8ecc4..7183d3197d 100644
--- a/Libraries/LibHTML/Layout/LayoutBox.h
+++ b/Libraries/LibHTML/Layout/LayoutBox.h
@@ -32,6 +32,14 @@ protected:
private:
virtual bool is_box() const override { return true; }
+ enum class Edge {
+ Top,
+ Right,
+ Bottom,
+ Left,
+ };
+ void paint_border(RenderingContext&, Edge, const Rect&, CSS::PropertyID style_property_id, CSS::PropertyID color_property_id, CSS::PropertyID width_property_id);
+
FloatRect m_rect;
};