mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:12:45 +00:00 
			
		
		
		
	LibGfx+LibWeb: Update for_each_glyph_position to use font cascade list
This change updates function that builds list of glyphs to use font cascade list to find font for each code point.
This commit is contained in:
		
							parent
							
								
									2cb0039a13
								
							
						
					
					
						commit
						df57d7ca68
					
				
					 8 changed files with 66 additions and 16 deletions
				
			
		
							
								
								
									
										
											BIN
										
									
								
								Tests/LibWeb/Ref/assets/HashSans.woff
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/LibWeb/Ref/assets/HashSans.woff
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										23
									
								
								Tests/LibWeb/Ref/reference/unicode-range-ref.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Tests/LibWeb/Ref/reference/unicode-range-ref.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | |||
| <!DOCTYPE html> | ||||
| <html> | ||||
| <head> | ||||
|     <style> | ||||
|         @font-face { | ||||
|             font-family: 'HashFont'; | ||||
|             src: url('../assets/HashSans.woff'); | ||||
|         } | ||||
| 
 | ||||
|         .hash-font { | ||||
|           font-family: 'HashFont'; | ||||
|         } | ||||
| 
 | ||||
|         .text { | ||||
|           font-size: 100px; | ||||
|           font-family: "SerenitySans"; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
| <body> | ||||
|     <div class="text"><span class="hash-font">A</span>B</div> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										21
									
								
								Tests/LibWeb/Ref/unicode-range.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Tests/LibWeb/Ref/unicode-range.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| <!DOCTYPE html> | ||||
| <html> | ||||
| <head> | ||||
|     <link rel="match" href="reference/unicode-range-ref.html" /> | ||||
|     <style> | ||||
|         @font-face { | ||||
|             font-family: 'HashFont'; | ||||
|             src: url('assets/HashSans.woff'); | ||||
|             unicode-range: U+0041; /* Only letter 'A' */ | ||||
|         } | ||||
| 
 | ||||
|         .text { | ||||
|             font-family: 'HashFont', 'SerenitySans'; | ||||
|             font-size: 100px; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
| <body> | ||||
|     <div class="text">AB</div> | ||||
| </body> | ||||
| </html> | ||||
|  | @ -2439,7 +2439,9 @@ void Painter::draw_text_run(IntPoint baseline_start, Utf8View const& string, Fon | |||
| 
 | ||||
| void Painter::draw_text_run(FloatPoint baseline_start, Utf8View const& string, Font const& font, Color color) | ||||
| { | ||||
|     for_each_glyph_position(baseline_start, string, font, [&](DrawGlyphOrEmoji glyph_or_emoji) { | ||||
|     auto font_list = Gfx::FontCascadeList::create(); | ||||
|     font_list->add(font); | ||||
|     for_each_glyph_position(baseline_start, string, font_list, [&](DrawGlyphOrEmoji glyph_or_emoji) { | ||||
|         if (glyph_or_emoji.has<DrawGlyph>()) { | ||||
|             auto& glyph = glyph_or_emoji.get<DrawGlyph>(); | ||||
|             draw_glyph(glyph.position, glyph.code_point, *glyph.font, color); | ||||
|  |  | |||
|  | @ -170,8 +170,10 @@ void Path::text(Utf8View text, Font const& font) | |||
|     } | ||||
| 
 | ||||
|     auto& scaled_font = static_cast<ScaledFont const&>(font); | ||||
|     auto font_list = Gfx::FontCascadeList::create(); | ||||
|     font_list->add(scaled_font); | ||||
|     for_each_glyph_position( | ||||
|         last_point(), text, font, [&](DrawGlyphOrEmoji glyph_or_emoji) { | ||||
|         last_point(), text, font_list, [&](DrawGlyphOrEmoji glyph_or_emoji) { | ||||
|             if (glyph_or_emoji.has<DrawGlyph>()) { | ||||
|                 auto& glyph = glyph_or_emoji.get<DrawGlyph>(); | ||||
|                 move_to(glyph.position); | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ | |||
| #include <AK/Utf8View.h> | ||||
| #include <AK/Vector.h> | ||||
| #include <LibGfx/Font/Font.h> | ||||
| #include <LibGfx/FontCascadeList.h> | ||||
| #include <LibGfx/Forward.h> | ||||
| #include <LibGfx/Rect.h> | ||||
| #include <LibGfx/TextElision.h> | ||||
|  | @ -92,34 +93,35 @@ using DrawGlyphOrEmoji = Variant<DrawGlyph, DrawEmoji>; | |||
| Variant<DrawGlyph, DrawEmoji> prepare_draw_glyph_or_emoji(FloatPoint point, Utf8CodePointIterator& it, Font const& font); | ||||
| 
 | ||||
| template<typename Callback> | ||||
| void for_each_glyph_position(FloatPoint baseline_start, Utf8View string, Font const& font, Callback callback, IncludeLeftBearing include_left_bearing = IncludeLeftBearing::No, Optional<float&> width = {}) | ||||
| void for_each_glyph_position(FloatPoint baseline_start, Utf8View string, FontCascadeList const& font_list, Callback callback, IncludeLeftBearing include_left_bearing = IncludeLeftBearing::No, Optional<float&> width = {}) | ||||
| { | ||||
|     float space_width = font.glyph_width(' ') + font.glyph_spacing(); | ||||
|     float space_width = font_list.first().glyph_width(' ') + font_list.first().glyph_spacing(); | ||||
| 
 | ||||
|     u32 last_code_point = 0; | ||||
| 
 | ||||
|     auto point = baseline_start; | ||||
|     point.translate_by(0, -font.pixel_metrics().ascent); | ||||
| 
 | ||||
|     for (auto code_point_iterator = string.begin(); code_point_iterator != string.end(); ++code_point_iterator) { | ||||
|         auto it = code_point_iterator; // The callback function will advance the iterator, so create a copy for this lookup.
 | ||||
|         auto code_point = *code_point_iterator; | ||||
|         RefPtr<Gfx::Font const> font = font_list.font_for_code_point(code_point); | ||||
| 
 | ||||
|         point.set_y(baseline_start.y() - font->pixel_metrics().ascent); | ||||
| 
 | ||||
|         if (should_paint_as_space(code_point)) { | ||||
|             point.translate_by(space_width, 0); | ||||
|             last_code_point = code_point; | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         auto kerning = font.glyphs_horizontal_kerning(last_code_point, code_point); | ||||
|         auto kerning = font->glyphs_horizontal_kerning(last_code_point, code_point); | ||||
|         if (kerning != 0.0f) | ||||
|             point.translate_by(kerning, 0); | ||||
| 
 | ||||
|         auto it = code_point_iterator; // The callback function will advance the iterator, so create a copy for this lookup.
 | ||||
|         auto glyph_width = font.glyph_or_emoji_width(it) + font.glyph_spacing(); | ||||
| 
 | ||||
|         auto glyph_or_emoji = prepare_draw_glyph_or_emoji(point, code_point_iterator, font); | ||||
|         auto glyph_width = font->glyph_or_emoji_width(it) + font->glyph_spacing(); | ||||
|         auto glyph_or_emoji = prepare_draw_glyph_or_emoji(point, code_point_iterator, *font); | ||||
|         if (include_left_bearing == IncludeLeftBearing::Yes) { | ||||
|             if (glyph_or_emoji.has<DrawGlyph>()) | ||||
|                 glyph_or_emoji.get<DrawGlyph>().position += FloatPoint(font.glyph_left_bearing(code_point), 0); | ||||
|                 glyph_or_emoji.get<DrawGlyph>().position += FloatPoint(font->glyph_left_bearing(code_point), 0); | ||||
|         } | ||||
| 
 | ||||
|         callback(glyph_or_emoji); | ||||
|  | @ -129,7 +131,7 @@ void for_each_glyph_position(FloatPoint baseline_start, Utf8View string, Font co | |||
|     } | ||||
| 
 | ||||
|     if (width.has_value()) | ||||
|         *width = point.x() - font.glyph_spacing(); | ||||
|         *width = point.x() - font_list.first().glyph_spacing(); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -190,7 +190,7 @@ Optional<InlineLevelIterator::Item> InlineLevelIterator::next_without_lookahead( | |||
|         Vector<Gfx::DrawGlyphOrEmoji> glyph_run; | ||||
|         float glyph_run_width = 0; | ||||
|         Gfx::for_each_glyph_position( | ||||
|             { 0, 0 }, chunk.view, text_node.first_available_font(), [&](Gfx::DrawGlyphOrEmoji const& glyph_or_emoji) { | ||||
|             { 0, 0 }, chunk.view, text_node.font_list(), [&](Gfx::DrawGlyphOrEmoji const& glyph_or_emoji) { | ||||
|                 glyph_run.append(glyph_or_emoji); | ||||
|                 return IterationDecision::Continue; | ||||
|             }, | ||||
|  |  | |||
|  | @ -638,12 +638,12 @@ static void paint_text_fragment(PaintContext& context, Layout::TextNode const& t | |||
|         auto text = text_node.text_for_rendering(); | ||||
| 
 | ||||
|         DevicePixelPoint baseline_start { fragment_absolute_device_rect.x(), fragment_absolute_device_rect.y() + context.rounded_device_pixels(fragment.baseline()) }; | ||||
|         auto const& scaled_font = fragment.layout_node().scaled_font(context); | ||||
|         Vector<Gfx::DrawGlyphOrEmoji> scaled_glyph_run; | ||||
|         scaled_glyph_run.ensure_capacity(fragment.glyph_run().size()); | ||||
|         auto& font_cache = text_node.document().style_computer().font_cache(); | ||||
|         for (auto glyph : fragment.glyph_run()) { | ||||
|             glyph.visit([&](auto& glyph) { | ||||
|                 glyph.font = scaled_font; | ||||
|                 glyph.font = font_cache.scaled_font(*glyph.font, context.device_pixels_per_css_pixel()); | ||||
|                 glyph.position = glyph.position.scaled(context.device_pixels_per_css_pixel()); | ||||
|             }); | ||||
|             scaled_glyph_run.append(move(glyph)); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Aliaksandr Kalenik
						Aliaksandr Kalenik