| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2021-04-17 23:10:10 +02:00
										 |  |  |  * Copyright (c) 2021, Tobias Christiansen <tobi@tobyase.de> | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-22 23:39:18 +02:00
										 |  |  | #include <AK/StringBuilder.h>
 | 
					
						
							| 
									
										
										
										
											2021-02-10 08:25:35 +01:00
										 |  |  | #include <LibGfx/Painter.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | #include <LibWeb/Layout/ListItemMarkerBox.h>
 | 
					
						
							| 
									
										
										
										
											2019-10-11 23:16:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | namespace Web::Layout { | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-17 23:10:10 +02:00
										 |  |  | ListItemMarkerBox::ListItemMarkerBox(DOM::Document& document, CSS::ListStyleType style_type, size_t index) | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  |     : Box(document, nullptr, CSS::StyleProperties::create()) | 
					
						
							| 
									
										
										
										
											2021-04-17 23:10:10 +02:00
										 |  |  |     , m_list_style_type(style_type) | 
					
						
							|  |  |  |     , m_index(index) | 
					
						
							| 
									
										
										
										
											2019-10-11 23:16:53 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-05-11 22:32:54 +02:00
										 |  |  |     switch (m_list_style_type) { | 
					
						
							|  |  |  |     case CSS::ListStyleType::Square: | 
					
						
							|  |  |  |     case CSS::ListStyleType::Circle: | 
					
						
							|  |  |  |     case CSS::ListStyleType::Disc: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::ListStyleType::Decimal: | 
					
						
							|  |  |  |         m_text = String::formatted("{}.", m_index); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::ListStyleType::DecimalLeadingZero: | 
					
						
							|  |  |  |         // This is weird, but in accordance to spec.
 | 
					
						
							|  |  |  |         m_text = m_index < 10 ? String::formatted("0{}.", m_index) : String::formatted("{}.", m_index); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::ListStyleType::LowerAlpha: | 
					
						
							|  |  |  |     case CSS::ListStyleType::LowerLatin: | 
					
						
							| 
									
										
										
										
											2021-05-13 13:49:15 +02:00
										 |  |  |         m_text = String::bijective_base_from(m_index - 1).to_lowercase(); | 
					
						
							| 
									
										
										
										
											2021-05-11 22:32:54 +02:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case CSS::ListStyleType::UpperAlpha: | 
					
						
							|  |  |  |     case CSS::ListStyleType::UpperLatin: | 
					
						
							| 
									
										
										
										
											2021-05-13 13:49:15 +02:00
										 |  |  |         m_text = String::bijective_base_from(m_index - 1); | 
					
						
							| 
									
										
										
										
											2021-05-11 22:32:54 +02:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-07-04 17:17:23 +02:00
										 |  |  |     case CSS::ListStyleType::LowerRoman: | 
					
						
							|  |  |  |         m_text = String::roman_number_from(m_index).to_lowercase(); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::ListStyleType::UpperRoman: | 
					
						
							|  |  |  |         m_text = String::roman_number_from(m_index); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-05-11 22:32:54 +02:00
										 |  |  |     case CSS::ListStyleType::None: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_text.is_null()) { | 
					
						
							|  |  |  |         set_width(4); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto text_width = font().width(m_text); | 
					
						
							|  |  |  |     set_width(text_width); | 
					
						
							| 
									
										
										
										
											2019-10-11 23:16:53 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | ListItemMarkerBox::~ListItemMarkerBox() | 
					
						
							| 
									
										
										
										
											2019-10-11 23:16:53 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | void ListItemMarkerBox::paint(PaintContext& context, PaintPhase phase) | 
					
						
							| 
									
										
										
										
											2019-10-11 23:16:53 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-18 18:57:35 +02:00
										 |  |  |     if (phase != PaintPhase::Foreground) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-04-17 23:11:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-19 11:54:28 +02:00
										 |  |  |     // FIXME: It would be nicer to not have to go via the parent here to get our inherited style.
 | 
					
						
							| 
									
										
										
										
											2021-01-06 10:34:31 +01:00
										 |  |  |     auto color = parent()->computed_values().color(); | 
					
						
							| 
									
										
										
										
											2021-04-17 23:11:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto enclosing = enclosing_int_rect(absolute_rect()); | 
					
						
							|  |  |  |     int marker_width = (int)enclosing.height() / 2; | 
					
						
							|  |  |  |     Gfx::IntRect marker_rect { 0, 0, marker_width, marker_width }; | 
					
						
							|  |  |  |     marker_rect.center_within(enclosing); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (m_list_style_type) { | 
					
						
							|  |  |  |     case CSS::ListStyleType::Square: | 
					
						
							|  |  |  |         context.painter().fill_rect(marker_rect, color); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::ListStyleType::Circle: | 
					
						
							|  |  |  |         // For some reason for draw_ellipse() the ellipse is outside of the rect while for fill_ellipse() the ellipse is inside.
 | 
					
						
							|  |  |  |         // Scale the marker_rect with sqrt(2) to get an ellipse arc (circle) that appears as if it was inside of the marker_rect.
 | 
					
						
							|  |  |  |         marker_rect.set_height(marker_rect.height() / 1.41); | 
					
						
							|  |  |  |         marker_rect.set_width(marker_rect.width() / 1.41); | 
					
						
							|  |  |  |         marker_rect.center_within(enclosing); | 
					
						
							|  |  |  |         context.painter().draw_ellipse_intersecting(marker_rect, color); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::ListStyleType::Disc: | 
					
						
							|  |  |  |         context.painter().fill_ellipse(marker_rect, color); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-05-11 22:32:54 +02:00
										 |  |  |     case CSS::ListStyleType::Decimal: | 
					
						
							| 
									
										
										
										
											2021-04-22 22:14:24 +02:00
										 |  |  |     case CSS::ListStyleType::DecimalLeadingZero: | 
					
						
							| 
									
										
										
										
											2021-04-22 23:39:18 +02:00
										 |  |  |     case CSS::ListStyleType::LowerAlpha: | 
					
						
							|  |  |  |     case CSS::ListStyleType::LowerLatin: | 
					
						
							| 
									
										
										
										
											2021-07-04 17:17:23 +02:00
										 |  |  |     case CSS::ListStyleType::LowerRoman: | 
					
						
							| 
									
										
										
										
											2021-04-22 23:52:15 +02:00
										 |  |  |     case CSS::ListStyleType::UpperAlpha: | 
					
						
							|  |  |  |     case CSS::ListStyleType::UpperLatin: | 
					
						
							| 
									
										
										
										
											2021-07-04 17:17:23 +02:00
										 |  |  |     case CSS::ListStyleType::UpperRoman: | 
					
						
							| 
									
										
										
										
											2021-05-11 22:32:54 +02:00
										 |  |  |         if (m_text.is_null()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         context.painter().draw_text(enclosing, m_text, Gfx::TextAlignment::Center); | 
					
						
							| 
									
										
										
										
											2021-04-22 23:52:15 +02:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-04-17 23:11:49 +02:00
										 |  |  |     case CSS::ListStyleType::None: | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-11 23:16:53 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | } |