mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:22:45 +00:00 
			
		
		
		
	LibWeb: Change paint_all_borders() to accept only device pixel values
By consistently accepting only device pixel values instead of a mix of CSSPixels and DevicePixels values, we can simplify the implementation of paint_border() and paint_all_borders().
This commit is contained in:
		
							parent
							
								
									ae8c98104a
								
							
						
					
					
						commit
						70353b79af
					
				
					 9 changed files with 152 additions and 88 deletions
				
			
		|  | @ -482,6 +482,7 @@ set(SOURCES | |||
|     Painting/BorderRadiiData.cpp | ||||
|     Painting/BorderPainting.cpp | ||||
|     Painting/BorderRadiusCornerClipper.cpp | ||||
|     Painting/BordersData.cpp | ||||
|     Painting/ButtonPaintable.cpp | ||||
|     Painting/CanvasPaintable.cpp | ||||
|     Painting/CheckBoxPaintable.cpp | ||||
|  |  | |||
|  | @ -85,7 +85,7 @@ static Color dark_color_for_inset_and_outset(Color const& color) | |||
|     return Color::from_hsv({ hsv.hue, hsv.saturation, hsv.value - dark_light_absolute_value_difference }); | ||||
| } | ||||
| 
 | ||||
| Gfx::Color border_color(BorderEdge edge, BordersData const& borders_data) | ||||
| Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_data) | ||||
| { | ||||
|     auto const& border_data = [&] { | ||||
|         switch (edge) { | ||||
|  | @ -115,7 +115,7 @@ Gfx::Color border_color(BorderEdge edge, BordersData const& borders_data) | |||
|     return border_data.color; | ||||
| } | ||||
| 
 | ||||
| void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersData const& borders_data, Gfx::Path& path, bool last) | ||||
| void paint_border(RecordingPainter& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path& path, bool last) | ||||
| { | ||||
|     auto const& border_data = [&] { | ||||
|         switch (edge) { | ||||
|  | @ -130,13 +130,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|         } | ||||
|     }(); | ||||
| 
 | ||||
|     CSSPixels width = border_data.width; | ||||
|     if (width <= 0) | ||||
|     if (border_data.width <= 0) | ||||
|         return; | ||||
| 
 | ||||
|     auto color = border_color(edge, borders_data); | ||||
|     auto border_style = border_data.line_style; | ||||
|     auto device_pixel_width = context.rounded_device_pixels(width); | ||||
| 
 | ||||
|     struct Points { | ||||
|         DevicePixelPoint p1; | ||||
|  | @ -183,27 +181,27 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|         auto [p1, p2] = points_for_edge(edge, rect); | ||||
|         switch (edge) { | ||||
|         case BorderEdge::Top: | ||||
|             p1.translate_by(device_pixel_width / 2, device_pixel_width / 2); | ||||
|             p2.translate_by(-device_pixel_width / 2, device_pixel_width / 2); | ||||
|             p1.translate_by(border_data.width / 2, border_data.width / 2); | ||||
|             p2.translate_by(-border_data.width / 2, border_data.width / 2); | ||||
|             break; | ||||
|         case BorderEdge::Right: | ||||
|             p1.translate_by(-device_pixel_width / 2, device_pixel_width / 2); | ||||
|             p2.translate_by(-device_pixel_width / 2, -device_pixel_width / 2); | ||||
|             p1.translate_by(-border_data.width / 2, border_data.width / 2); | ||||
|             p2.translate_by(-border_data.width / 2, -border_data.width / 2); | ||||
|             break; | ||||
|         case BorderEdge::Bottom: | ||||
|             p1.translate_by(device_pixel_width / 2, -device_pixel_width / 2); | ||||
|             p2.translate_by(-device_pixel_width / 2, -device_pixel_width / 2); | ||||
|             p1.translate_by(border_data.width / 2, -border_data.width / 2); | ||||
|             p2.translate_by(-border_data.width / 2, -border_data.width / 2); | ||||
|             break; | ||||
|         case BorderEdge::Left: | ||||
|             p1.translate_by(device_pixel_width / 2, device_pixel_width / 2); | ||||
|             p2.translate_by(device_pixel_width / 2, -device_pixel_width / 2); | ||||
|             p1.translate_by(border_data.width / 2, border_data.width / 2); | ||||
|             p2.translate_by(border_data.width / 2, -border_data.width / 2); | ||||
|             break; | ||||
|         } | ||||
|         if (border_style == CSS::LineStyle::Dotted) { | ||||
|             context.painter().draw_line(p1.to_type<int>(), p2.to_type<int>(), color, device_pixel_width.value(), gfx_line_style); | ||||
|             painter.draw_line(p1.to_type<int>(), p2.to_type<int>(), color, border_data.width.value(), gfx_line_style); | ||||
|             return; | ||||
|         } | ||||
|         context.painter().draw_line(p1.to_type<int>(), p2.to_type<int>(), color, device_pixel_width.value(), gfx_line_style); | ||||
|         painter.draw_line(p1.to_type<int>(), p2.to_type<int>(), color, border_data.width.value(), gfx_line_style); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -245,7 +243,7 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|         // If joined borders have the same color, combine them to draw together.
 | ||||
|         if (ready_to_draw) { | ||||
|             path.close_all_subpaths(); | ||||
|             context.painter().fill_path({ .path = path, .color = color, .winding_rule = Gfx::Painter::WindingRule::EvenOdd }); | ||||
|             painter.fill_path({ .path = path, .color = color, .winding_rule = Gfx::Painter::WindingRule::EvenOdd }); | ||||
|             path.clear(); | ||||
|         } | ||||
|     }; | ||||
|  | @ -285,10 +283,10 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|      */ | ||||
|     switch (edge) { | ||||
|     case BorderEdge::Top: { | ||||
|         auto joined_border_width = context.enclosing_device_pixels(borders_data.left.width); | ||||
|         auto opposite_joined_border_width = context.enclosing_device_pixels(borders_data.right.width); | ||||
|         bool joined_corner_has_inner_corner = device_pixel_width < radius.vertical_radius && joined_border_width < radius.horizontal_radius; | ||||
|         bool opposite_joined_corner_has_inner_corner = device_pixel_width < opposite_radius.vertical_radius && opposite_joined_border_width < opposite_radius.horizontal_radius; | ||||
|         auto joined_border_width = borders_data.left.width; | ||||
|         auto opposite_joined_border_width = borders_data.right.width; | ||||
|         bool joined_corner_has_inner_corner = border_data.width < radius.vertical_radius && joined_border_width < radius.horizontal_radius; | ||||
|         bool opposite_joined_corner_has_inner_corner = border_data.width < opposite_radius.vertical_radius && opposite_joined_border_width < opposite_radius.horizontal_radius; | ||||
| 
 | ||||
|         Gfx::FloatPoint joined_corner_endpoint_offset; | ||||
|         Gfx::FloatPoint opposite_joined_border_corner_offset; | ||||
|  | @ -310,11 +308,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|         if (joined_corner_has_inner_corner) { | ||||
|             Gfx::FloatPoint midpoint = compute_midpoint( | ||||
|                 radius.horizontal_radius - joined_border_width.value(), | ||||
|                 radius.vertical_radius - device_pixel_width.value(), | ||||
|                 radius.vertical_radius - border_data.width.value(), | ||||
|                 joined_border_width.value()); | ||||
|             Gfx::FloatPoint inner_corner_endpoint_offset = Gfx::FloatPoint( | ||||
|                 -midpoint.x(), | ||||
|                 radius.vertical_radius - device_pixel_width.value() - midpoint.y()); | ||||
|                 radius.vertical_radius - border_data.width.value() - midpoint.y()); | ||||
|             points.append(Gfx::FloatPoint(rect.bottom_left().to_type<int>()) + inner_corner_endpoint_offset); | ||||
|             points.append(Gfx::FloatPoint(rect.bottom_left().to_type<int>())); | ||||
|         } else { | ||||
|  | @ -327,11 +325,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|         if (opposite_joined_corner_has_inner_corner) { | ||||
|             Gfx::FloatPoint midpoint = compute_midpoint( | ||||
|                 opposite_radius.horizontal_radius - opposite_joined_border_width.value(), | ||||
|                 opposite_radius.vertical_radius - device_pixel_width.value(), | ||||
|                 opposite_radius.vertical_radius - border_data.width.value(), | ||||
|                 opposite_joined_border_width.value()); | ||||
|             Gfx::FloatPoint inner_corner_endpoint_offset = Gfx::FloatPoint( | ||||
|                 midpoint.x(), | ||||
|                 opposite_radius.vertical_radius - device_pixel_width.value() - midpoint.y()); | ||||
|                 opposite_radius.vertical_radius - border_data.width.value() - midpoint.y()); | ||||
|             points.append(Gfx::FloatPoint(rect.bottom_right().to_type<int>())); | ||||
|             points.append(Gfx::FloatPoint(rect.bottom_right().to_type<int>()) + inner_corner_endpoint_offset); | ||||
|         } else { | ||||
|  | @ -348,16 +346,16 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|             points, | ||||
|             joined_corner_has_inner_corner, | ||||
|             opposite_joined_corner_has_inner_corner, | ||||
|             Gfx::FloatSize(joined_border_width.value(), device_pixel_width.value()), | ||||
|             Gfx::FloatSize(opposite_joined_border_width.value(), device_pixel_width.value()), | ||||
|             Gfx::FloatSize(joined_border_width.value(), border_data.width.value()), | ||||
|             Gfx::FloatSize(opposite_joined_border_width.value(), border_data.width.value()), | ||||
|             last || color != border_color(BorderEdge::Right, borders_data)); | ||||
|         break; | ||||
|     } | ||||
|     case BorderEdge::Right: { | ||||
|         auto joined_border_width = context.enclosing_device_pixels(borders_data.top.width); | ||||
|         auto opposite_joined_border_width = context.enclosing_device_pixels(borders_data.bottom.width); | ||||
|         bool joined_corner_has_inner_corner = device_pixel_width < radius.horizontal_radius && joined_border_width < radius.vertical_radius; | ||||
|         bool opposite_joined_corner_has_inner_corner = device_pixel_width < opposite_radius.horizontal_radius && opposite_joined_border_width < opposite_radius.vertical_radius; | ||||
|         auto joined_border_width = borders_data.top.width; | ||||
|         auto opposite_joined_border_width = borders_data.bottom.width; | ||||
|         bool joined_corner_has_inner_corner = border_data.width < radius.horizontal_radius && joined_border_width < radius.vertical_radius; | ||||
|         bool opposite_joined_corner_has_inner_corner = border_data.width < opposite_radius.horizontal_radius && opposite_joined_border_width < opposite_radius.vertical_radius; | ||||
| 
 | ||||
|         Gfx::FloatPoint joined_corner_endpoint_offset; | ||||
|         Gfx::FloatPoint opposite_joined_border_corner_offset; | ||||
|  | @ -378,11 +376,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
| 
 | ||||
|         if (joined_corner_has_inner_corner) { | ||||
|             auto midpoint = compute_midpoint( | ||||
|                 radius.horizontal_radius - device_pixel_width.value(), | ||||
|                 radius.horizontal_radius - border_data.width.value(), | ||||
|                 radius.vertical_radius - joined_border_width.value(), | ||||
|                 joined_border_width.value()); | ||||
|             Gfx::FloatPoint inner_corner = Gfx::FloatPoint( | ||||
|                 -(radius.horizontal_radius - midpoint.x() - device_pixel_width.value()), | ||||
|                 -(radius.horizontal_radius - midpoint.x() - border_data.width.value()), | ||||
|                 -midpoint.y()); | ||||
|             points.append(Gfx::FloatPoint(rect.top_left().to_type<int>()) + inner_corner); | ||||
|             points.append(Gfx::FloatPoint(rect.top_left().to_type<int>())); | ||||
|  | @ -393,11 +391,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
| 
 | ||||
|         if (opposite_joined_corner_has_inner_corner) { | ||||
|             auto midpoint = compute_midpoint( | ||||
|                 opposite_radius.horizontal_radius - device_pixel_width.value(), | ||||
|                 opposite_radius.horizontal_radius - border_data.width.value(), | ||||
|                 opposite_radius.vertical_radius - opposite_joined_border_width.value(), | ||||
|                 opposite_joined_border_width.value()); | ||||
|             Gfx::FloatPoint inner_corner = Gfx::FloatPoint( | ||||
|                 -(opposite_radius.horizontal_radius - midpoint.x() - device_pixel_width.value()), | ||||
|                 -(opposite_radius.horizontal_radius - midpoint.x() - border_data.width.value()), | ||||
|                 midpoint.y()); | ||||
|             points.append(Gfx::FloatPoint(rect.bottom_left().to_type<int>())); | ||||
|             points.append(Gfx::FloatPoint(rect.bottom_left().to_type<int>()) + inner_corner); | ||||
|  | @ -413,16 +411,16 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|             points, | ||||
|             joined_corner_has_inner_corner, | ||||
|             opposite_joined_corner_has_inner_corner, | ||||
|             Gfx::FloatSize(device_pixel_width.value(), joined_border_width.value()), | ||||
|             Gfx::FloatSize(device_pixel_width.value(), opposite_joined_border_width.value()), | ||||
|             Gfx::FloatSize(border_data.width.value(), joined_border_width.value()), | ||||
|             Gfx::FloatSize(border_data.width.value(), opposite_joined_border_width.value()), | ||||
|             last || color != border_color(BorderEdge::Bottom, borders_data)); | ||||
|         break; | ||||
|     } | ||||
|     case BorderEdge::Bottom: { | ||||
|         auto joined_border_width = context.enclosing_device_pixels(borders_data.right.width); | ||||
|         auto opposite_joined_border_width = context.enclosing_device_pixels(borders_data.left.width); | ||||
|         bool joined_corner_has_inner_corner = device_pixel_width < radius.vertical_radius && joined_border_width < radius.horizontal_radius; | ||||
|         bool opposite_joined_corner_has_inner_corner = device_pixel_width < opposite_radius.vertical_radius && opposite_joined_border_width < opposite_radius.horizontal_radius; | ||||
|         auto joined_border_width = borders_data.right.width; | ||||
|         auto opposite_joined_border_width = borders_data.left.width; | ||||
|         bool joined_corner_has_inner_corner = border_data.width < radius.vertical_radius && joined_border_width < radius.horizontal_radius; | ||||
|         bool opposite_joined_corner_has_inner_corner = border_data.width < opposite_radius.vertical_radius && opposite_joined_border_width < opposite_radius.horizontal_radius; | ||||
| 
 | ||||
|         Gfx::FloatPoint joined_corner_endpoint_offset; | ||||
|         Gfx::FloatPoint opposite_joined_border_corner_offset; | ||||
|  | @ -444,9 +442,9 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|         if (joined_corner_has_inner_corner) { | ||||
|             auto midpoint = compute_midpoint( | ||||
|                 radius.horizontal_radius - joined_border_width.value(), | ||||
|                 radius.vertical_radius - device_pixel_width.value(), | ||||
|                 radius.vertical_radius - border_data.width.value(), | ||||
|                 joined_border_width.value()); | ||||
|             Gfx::FloatPoint inner_corner = Gfx::FloatPoint(midpoint.x(), -(radius.vertical_radius - midpoint.y() - device_pixel_width.value())); | ||||
|             Gfx::FloatPoint inner_corner = Gfx::FloatPoint(midpoint.x(), -(radius.vertical_radius - midpoint.y() - border_data.width.value())); | ||||
|             points.append(Gfx::FloatPoint(rect.top_right().to_type<int>()) + inner_corner); | ||||
|             points.append(Gfx::FloatPoint(rect.top_right().to_type<int>())); | ||||
|         } else { | ||||
|  | @ -457,11 +455,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|         if (opposite_joined_corner_has_inner_corner) { | ||||
|             auto midpoint = compute_midpoint( | ||||
|                 opposite_radius.horizontal_radius - opposite_joined_border_width.value(), | ||||
|                 opposite_radius.vertical_radius - device_pixel_width.value(), | ||||
|                 opposite_radius.vertical_radius - border_data.width.value(), | ||||
|                 opposite_joined_border_width.value()); | ||||
|             Gfx::FloatPoint inner_corner = Gfx::FloatPoint( | ||||
|                 -midpoint.x(), | ||||
|                 -(opposite_radius.vertical_radius - midpoint.y() - device_pixel_width.value())); | ||||
|                 -(opposite_radius.vertical_radius - midpoint.y() - border_data.width.value())); | ||||
|             points.append(Gfx::FloatPoint(rect.top_left().to_type<int>())); | ||||
|             points.append(Gfx::FloatPoint(rect.top_left().to_type<int>()) + inner_corner); | ||||
|         } else { | ||||
|  | @ -475,16 +473,16 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|             points, | ||||
|             joined_corner_has_inner_corner, | ||||
|             opposite_joined_corner_has_inner_corner, | ||||
|             Gfx::FloatSize(joined_border_width.value(), device_pixel_width.value()), | ||||
|             Gfx::FloatSize(opposite_joined_border_width.value(), device_pixel_width.value()), | ||||
|             Gfx::FloatSize(joined_border_width.value(), border_data.width.value()), | ||||
|             Gfx::FloatSize(opposite_joined_border_width.value(), border_data.width.value()), | ||||
|             last || color != border_color(BorderEdge::Left, borders_data)); | ||||
|         break; | ||||
|     } | ||||
|     case BorderEdge::Left: { | ||||
|         auto joined_border_width = context.enclosing_device_pixels(borders_data.bottom.width); | ||||
|         auto opposite_joined_border_width = context.enclosing_device_pixels(borders_data.top.width); | ||||
|         bool joined_corner_has_inner_corner = device_pixel_width < radius.horizontal_radius && joined_border_width < radius.vertical_radius; | ||||
|         bool opposite_joined_corner_has_inner_corner = device_pixel_width < opposite_radius.horizontal_radius && opposite_joined_border_width < opposite_radius.vertical_radius; | ||||
|         auto joined_border_width = borders_data.bottom.width; | ||||
|         auto opposite_joined_border_width = borders_data.top.width; | ||||
|         bool joined_corner_has_inner_corner = border_data.width < radius.horizontal_radius && joined_border_width < radius.vertical_radius; | ||||
|         bool opposite_joined_corner_has_inner_corner = border_data.width < opposite_radius.horizontal_radius && opposite_joined_border_width < opposite_radius.vertical_radius; | ||||
| 
 | ||||
|         Gfx::FloatPoint joined_corner_endpoint_offset; | ||||
|         Gfx::FloatPoint opposite_joined_border_corner_offset; | ||||
|  | @ -505,10 +503,10 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
| 
 | ||||
|         if (joined_corner_has_inner_corner) { | ||||
|             auto midpoint = compute_midpoint( | ||||
|                 radius.horizontal_radius - device_pixel_width.value(), | ||||
|                 radius.horizontal_radius - border_data.width.value(), | ||||
|                 radius.vertical_radius - joined_border_width.value(), | ||||
|                 joined_border_width.value()); | ||||
|             Gfx::FloatPoint inner_corner = Gfx::FloatPoint(radius.horizontal_radius - device_pixel_width.value() - midpoint.x(), midpoint.y()); | ||||
|             Gfx::FloatPoint inner_corner = Gfx::FloatPoint(radius.horizontal_radius - border_data.width.value() - midpoint.x(), midpoint.y()); | ||||
|             points.append(Gfx::FloatPoint(rect.bottom_right().to_type<int>()) + inner_corner); | ||||
|             points.append(Gfx::FloatPoint(rect.bottom_right().to_type<int>())); | ||||
|         } else { | ||||
|  | @ -518,11 +516,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
| 
 | ||||
|         if (opposite_joined_corner_has_inner_corner) { | ||||
|             auto midpoint = compute_midpoint( | ||||
|                 opposite_radius.horizontal_radius - device_pixel_width.value(), | ||||
|                 opposite_radius.horizontal_radius - border_data.width.value(), | ||||
|                 opposite_radius.vertical_radius - opposite_joined_border_width.value(), | ||||
|                 opposite_joined_border_width.value()); | ||||
|             Gfx::FloatPoint inner_corner = Gfx::FloatPoint( | ||||
|                 opposite_radius.horizontal_radius - device_pixel_width.value() - midpoint.x(), | ||||
|                 opposite_radius.horizontal_radius - border_data.width.value() - midpoint.x(), | ||||
|                 -midpoint.y()); | ||||
|             points.append(Gfx::FloatPoint(rect.top_right().to_type<int>())); | ||||
|             points.append(Gfx::FloatPoint(rect.top_right().to_type<int>()) + inner_corner); | ||||
|  | @ -537,23 +535,23 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& | |||
|             points, | ||||
|             joined_corner_has_inner_corner, | ||||
|             opposite_joined_corner_has_inner_corner, | ||||
|             Gfx::FloatSize(device_pixel_width.value(), joined_border_width.value()), | ||||
|             Gfx::FloatSize(device_pixel_width.value(), opposite_joined_border_width.value()), | ||||
|             Gfx::FloatSize(border_data.width.value(), joined_border_width.value()), | ||||
|             Gfx::FloatSize(border_data.width.value(), opposite_joined_border_width.value()), | ||||
|             last || color != border_color(BorderEdge::Top, borders_data)); | ||||
|         break; | ||||
|     } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void paint_all_borders(PaintContext& context, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii_data, BordersData const& borders_data) | ||||
| void paint_all_borders(RecordingPainter& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data) | ||||
| { | ||||
|     if (borders_data.top.width <= 0 && borders_data.right.width <= 0 && borders_data.left.width <= 0 && borders_data.bottom.width <= 0) | ||||
|         return; | ||||
| 
 | ||||
|     auto top_left = border_radii_data.top_left.as_corner(context); | ||||
|     auto top_right = border_radii_data.top_right.as_corner(context); | ||||
|     auto bottom_right = border_radii_data.bottom_right.as_corner(context); | ||||
|     auto bottom_left = border_radii_data.bottom_left.as_corner(context); | ||||
|     auto top_left = corner_radii.top_left; | ||||
|     auto top_right = corner_radii.top_right; | ||||
|     auto bottom_right = corner_radii.bottom_right; | ||||
|     auto bottom_left = corner_radii.bottom_left; | ||||
| 
 | ||||
|     // Disable border radii if the corresponding borders don't exist:
 | ||||
|     if (borders_data.bottom.width <= 0 && borders_data.left.width <= 0) | ||||
|  | @ -569,24 +567,24 @@ void paint_all_borders(PaintContext& context, DevicePixelRect const& border_rect | |||
|         border_rect.x() + top_left.horizontal_radius, | ||||
|         border_rect.y(), | ||||
|         border_rect.width() - top_left.horizontal_radius - top_right.horizontal_radius, | ||||
|         context.enclosing_device_pixels(borders_data.top.width) | ||||
|         borders_data.top.width | ||||
|     }; | ||||
|     DevicePixelRect right_border_rect = { | ||||
|         border_rect.x() + (border_rect.width() - context.enclosing_device_pixels(borders_data.right.width)), | ||||
|         border_rect.x() + (border_rect.width() - borders_data.right.width), | ||||
|         border_rect.y() + top_right.vertical_radius, | ||||
|         context.enclosing_device_pixels(borders_data.right.width), | ||||
|         borders_data.right.width, | ||||
|         border_rect.height() - top_right.vertical_radius - bottom_right.vertical_radius | ||||
|     }; | ||||
|     DevicePixelRect bottom_border_rect = { | ||||
|         border_rect.x() + bottom_left.horizontal_radius, | ||||
|         border_rect.y() + (border_rect.height() - context.enclosing_device_pixels(borders_data.bottom.width)), | ||||
|         border_rect.y() + (border_rect.height() - borders_data.bottom.width), | ||||
|         border_rect.width() - bottom_left.horizontal_radius - bottom_right.horizontal_radius, | ||||
|         context.enclosing_device_pixels(borders_data.bottom.width) | ||||
|         borders_data.bottom.width | ||||
|     }; | ||||
|     DevicePixelRect left_border_rect = { | ||||
|         border_rect.x(), | ||||
|         border_rect.y() + top_left.vertical_radius, | ||||
|         context.enclosing_device_pixels(borders_data.left.width), | ||||
|         borders_data.left.width, | ||||
|         border_rect.height() - top_left.vertical_radius - bottom_left.vertical_radius | ||||
|     }; | ||||
| 
 | ||||
|  | @ -611,16 +609,16 @@ void paint_all_borders(PaintContext& context, DevicePixelRect const& border_rect | |||
|     for (BorderEdge edge : borders) { | ||||
|         switch (edge) { | ||||
|         case BorderEdge::Top: | ||||
|             paint_border(context, BorderEdge::Top, top_border_rect, top_left, top_right, borders_data, path, edge == borders.last()); | ||||
|             paint_border(painter, BorderEdge::Top, top_border_rect, top_left, top_right, borders_data, path, edge == borders.last()); | ||||
|             break; | ||||
|         case BorderEdge::Right: | ||||
|             paint_border(context, BorderEdge::Right, right_border_rect, top_right, bottom_right, borders_data, path, edge == borders.last()); | ||||
|             paint_border(painter, BorderEdge::Right, right_border_rect, top_right, bottom_right, borders_data, path, edge == borders.last()); | ||||
|             break; | ||||
|         case BorderEdge::Bottom: | ||||
|             paint_border(context, BorderEdge::Bottom, bottom_border_rect, bottom_right, bottom_left, borders_data, path, edge == borders.last()); | ||||
|             paint_border(painter, BorderEdge::Bottom, bottom_border_rect, bottom_right, bottom_left, borders_data, path, edge == borders.last()); | ||||
|             break; | ||||
|         case BorderEdge::Left: | ||||
|             paint_border(context, BorderEdge::Left, left_border_rect, bottom_left, top_left, borders_data, path, edge == borders.last()); | ||||
|             paint_border(painter, BorderEdge::Left, left_border_rect, bottom_left, top_left, borders_data, path, edge == borders.last()); | ||||
|             break; | ||||
|         default: | ||||
|             VERIFY_NOT_REACHED(); | ||||
|  |  | |||
|  | @ -28,9 +28,9 @@ enum class BorderEdge { | |||
| // Returns OptionalNone if there is no outline to paint.
 | ||||
| Optional<BordersData> borders_data_for_outline(Layout::Node const&, Color outline_color, CSS::OutlineStyle outline_style, CSSPixels outline_width); | ||||
| 
 | ||||
| void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersData const& borders_data, Gfx::Path& path, bool last); | ||||
| void paint_all_borders(PaintContext& context, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii_data, BordersData const&); | ||||
| void paint_border(RecordingPainter& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path& path, bool last); | ||||
| void paint_all_borders(RecordingPainter& context, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const&); | ||||
| 
 | ||||
| Gfx::Color border_color(BorderEdge edge, BordersData const& borders_data); | ||||
| Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_data); | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -33,6 +33,15 @@ struct BorderRadiusData { | |||
|     } | ||||
| }; | ||||
| 
 | ||||
| using CornerRadius = Gfx::AntiAliasingPainter::CornerRadius; | ||||
| 
 | ||||
| struct CornerRadii { | ||||
|     CornerRadius top_left; | ||||
|     CornerRadius top_right; | ||||
|     CornerRadius bottom_right; | ||||
|     CornerRadius bottom_left; | ||||
| }; | ||||
| 
 | ||||
| struct BorderRadiiData { | ||||
|     BorderRadiusData top_left; | ||||
|     BorderRadiusData top_right; | ||||
|  | @ -56,15 +65,16 @@ struct BorderRadiiData { | |||
|     { | ||||
|         shrink(-top, -right, -bottom, -left); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| using CornerRadius = Gfx::AntiAliasingPainter::CornerRadius; | ||||
| 
 | ||||
| struct CornerRadii { | ||||
|     CornerRadius top_left; | ||||
|     CornerRadius top_right; | ||||
|     CornerRadius bottom_right; | ||||
|     CornerRadius bottom_left; | ||||
|     inline CornerRadii as_corners(PaintContext& context) const | ||||
|     { | ||||
|         return CornerRadii { | ||||
|             top_left.as_corner(context), | ||||
|             top_right.as_corner(context), | ||||
|             bottom_right.as_corner(context), | ||||
|             bottom_left.as_corner(context) | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
							
								
								
									
										34
									
								
								Userland/Libraries/LibWeb/Painting/BordersData.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Userland/Libraries/LibWeb/Painting/BordersData.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #include <LibWeb/Painting/BordersData.h> | ||||
| #include <LibWeb/Painting/PaintContext.h> | ||||
| 
 | ||||
| namespace Web::Painting { | ||||
| 
 | ||||
| BordersDataDevicePixels BordersData::to_device_pixels(PaintContext const& context) const | ||||
| { | ||||
|     return BordersDataDevicePixels { | ||||
|         BorderDataDevicePixels { | ||||
|             top.color, | ||||
|             top.line_style, | ||||
|             context.enclosing_device_pixels(top.width).value() }, | ||||
|         BorderDataDevicePixels { | ||||
|             right.color, | ||||
|             right.line_style, | ||||
|             context.enclosing_device_pixels(right.width).value() }, | ||||
|         BorderDataDevicePixels { | ||||
|             bottom.color, | ||||
|             bottom.line_style, | ||||
|             context.enclosing_device_pixels(bottom.width).value() }, | ||||
|         BorderDataDevicePixels { | ||||
|             left.color, | ||||
|             left.line_style, | ||||
|             context.enclosing_device_pixels(left.width).value() } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  | @ -7,13 +7,34 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <LibGfx/Color.h> | ||||
| #include <LibWeb/CSS/ComputedValues.h> | ||||
| #include <LibWeb/CSS/Enums.h> | ||||
| #include <LibWeb/PixelUnits.h> | ||||
| 
 | ||||
| namespace Web::Painting { | ||||
| 
 | ||||
| struct BorderDataDevicePixels { | ||||
| public: | ||||
|     Color color { Color::Transparent }; | ||||
|     CSS::LineStyle line_style { CSS::LineStyle::None }; | ||||
|     DevicePixels width { 0 }; | ||||
| }; | ||||
| 
 | ||||
| struct BordersDataDevicePixels { | ||||
|     BorderDataDevicePixels top; | ||||
|     BorderDataDevicePixels right; | ||||
|     BorderDataDevicePixels bottom; | ||||
|     BorderDataDevicePixels left; | ||||
| }; | ||||
| 
 | ||||
| struct BordersData { | ||||
|     CSS::BorderData top; | ||||
|     CSS::BorderData right; | ||||
|     CSS::BorderData bottom; | ||||
|     CSS::BorderData left; | ||||
| 
 | ||||
|     BordersDataDevicePixels to_device_pixels(PaintContext const& context) const; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -134,9 +134,9 @@ void InlinePaintable::paint(PaintContext& context, PaintPhase phase) const | |||
| 
 | ||||
|                 border_radii_data.inflate(outline_data->top.width + outline_offset_y, outline_data->right.width + outline_offset_x, outline_data->bottom.width + outline_offset_y, outline_data->left.width + outline_offset_x); | ||||
|                 borders_rect.inflate(outline_data->top.width + outline_offset_y, outline_data->right.width + outline_offset_x, outline_data->bottom.width + outline_offset_y, outline_data->left.width + outline_offset_x); | ||||
|                 paint_all_borders(context, context.rounded_device_rect(borders_rect), border_radii_data, *outline_data); | ||||
|                 paint_all_borders(context.painter(), context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), outline_data->to_device_pixels(context)); | ||||
|             } else { | ||||
|                 paint_all_borders(context, context.rounded_device_rect(borders_rect), border_radii_data, borders_data); | ||||
|                 paint_all_borders(context.painter(), context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), borders_data.to_device_pixels(context)); | ||||
|             } | ||||
| 
 | ||||
|             return IterationDecision::Continue; | ||||
|  |  | |||
|  | @ -246,7 +246,7 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const | |||
|             border_radius_data.inflate(outline_width + outline_offset_y, outline_width + outline_offset_x, outline_width + outline_offset_y, outline_width + outline_offset_x); | ||||
|             borders_rect.inflate(outline_width + outline_offset_y, outline_width + outline_offset_x, outline_width + outline_offset_y, outline_width + outline_offset_x); | ||||
| 
 | ||||
|             paint_all_borders(context, context.rounded_device_rect(borders_rect), border_radius_data, borders_data.value()); | ||||
|             paint_all_borders(context.painter(), context.rounded_device_rect(borders_rect), border_radius_data.as_corners(context), borders_data->to_device_pixels(context)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -313,7 +313,7 @@ void PaintableBox::paint_border(PaintContext& context) const | |||
|         .bottom = box_model().border.bottom == 0 ? CSS::BorderData() : computed_values().border_bottom(), | ||||
|         .left = box_model().border.left == 0 ? CSS::BorderData() : computed_values().border_left(), | ||||
|     }; | ||||
|     paint_all_borders(context, context.rounded_device_rect(absolute_border_box_rect()), normalized_border_radii_data(), borders_data); | ||||
|     paint_all_borders(context.painter(), context.rounded_device_rect(absolute_border_box_rect()), normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context)); | ||||
| } | ||||
| 
 | ||||
| void PaintableBox::paint_backdrop_filter(PaintContext& context) const | ||||
|  |  | |||
|  | @ -351,7 +351,7 @@ static void paint_separate_cell_borders(PaintableBox const& cell_box, HashMap<Ce | |||
|         .left = cell_box.box_model().border.left == 0 ? CSS::BorderData() : cell_box.computed_values().border_left(), | ||||
|     }; | ||||
|     auto cell_rect = cell_coordinates_to_device_rect.get({ cell_box.table_cell_coordinates()->row_index, cell_box.table_cell_coordinates()->column_index }).value(); | ||||
|     paint_all_borders(context, cell_rect, cell_box.normalized_border_radii_data(), borders_data); | ||||
|     paint_all_borders(context.painter(), cell_rect, cell_box.normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context)); | ||||
| } | ||||
| 
 | ||||
| void paint_table_borders(PaintContext& context, PaintableBox const& table_paintable) | ||||
|  | @ -436,7 +436,7 @@ void paint_table_borders(PaintContext& context, PaintableBox const& table_painta | |||
|                 .bottom = cell_box.box_model().border.bottom == 0 ? CSS::BorderData() : cell_box.computed_values().border_bottom(), | ||||
|                 .left = cell_box.box_model().border.left == 0 ? CSS::BorderData() : cell_box.computed_values().border_left(), | ||||
|             }; | ||||
|             paint_all_borders(context, context.rounded_device_rect(cell_box.absolute_border_box_rect()), cell_box.normalized_border_radii_data(), borders_data); | ||||
|             paint_all_borders(context.painter(), context.rounded_device_rect(cell_box.absolute_border_box_rect()), cell_box.normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Aliaksandr Kalenik
						Aliaksandr Kalenik