| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2020, Matthew Olsson <matthewcolsson@gmail.com> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:03:24 +04:30
										 |  |  | #include <LibGfx/AntiAliasingPainter.h>
 | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  | #include <LibGfx/Painter.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | #include <LibWeb/Layout/SVGPathBox.h>
 | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  | #include <LibWeb/SVG/SVGPathElement.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | namespace Web::Layout { | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | SVGPathBox::SVGPathBox(DOM::Document& document, SVG::SVGPathElement& element, NonnullRefPtr<CSS::StyleProperties> properties) | 
					
						
							|  |  |  |     : SVGGraphicsBox(document, element, properties) | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | void SVGPathBox::prepare_for_replaced_layout() | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-11-22 14:46:36 +01:00
										 |  |  |     auto& bounding_box = dom_node().get_path().bounding_box(); | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  |     set_has_intrinsic_width(true); | 
					
						
							|  |  |  |     set_has_intrinsic_height(true); | 
					
						
							|  |  |  |     set_intrinsic_width(bounding_box.width()); | 
					
						
							|  |  |  |     set_intrinsic_height(bounding_box.height()); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // FIXME: This does not belong here! Someone at a higher level should place this box.
 | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  |     set_offset(bounding_box.top_left()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | void SVGPathBox::paint(PaintContext& context, PaintPhase phase) | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!is_visible()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  |     SVGGraphicsBox::paint(context, phase); | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  |     if (phase != PaintPhase::Foreground) | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 14:46:36 +01:00
										 |  |  |     auto& path_element = dom_node(); | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  |     auto& path = path_element.get_path(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // We need to fill the path before applying the stroke, however the filled
 | 
					
						
							|  |  |  |     // path must be closed, whereas the stroke path may not necessary be closed.
 | 
					
						
							|  |  |  |     // Copy the path and close it for filling, but use the previous path for stroke
 | 
					
						
							|  |  |  |     auto closed_path = path; | 
					
						
							|  |  |  |     closed_path.close(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Fills are computed as though all paths are closed (https://svgwg.org/svg2-draft/painting.html#FillProperties)
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:03:24 +04:30
										 |  |  |     Gfx::AntiAliasingPainter painter { context.painter() }; | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  |     auto& svg_context = context.svg_context(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:03:24 +04:30
										 |  |  |     auto offset = absolute_position() - effective_offset(); | 
					
						
							| 
									
										
										
										
											2020-10-05 16:14:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     painter.translate(offset); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     painter.fill_path( | 
					
						
							|  |  |  |         closed_path, | 
					
						
							|  |  |  |         path_element.fill_color().value_or(svg_context.fill_color()), | 
					
						
							|  |  |  |         Gfx::Painter::WindingRule::EvenOdd); | 
					
						
							|  |  |  |     painter.stroke_path( | 
					
						
							|  |  |  |         path, | 
					
						
							|  |  |  |         path_element.stroke_color().value_or(svg_context.stroke_color()), | 
					
						
							|  |  |  |         path_element.stroke_width().value_or(svg_context.stroke_width())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     painter.translate(-offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |