mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 02:37:35 +00:00
LibGfx+LibWeb: Calculate and save glyph positions during layout
Previously, we determined the positions of glyphs for each text run at the time of painting, which constituted a significant portion of the painting process according to profiles. However, since we already go through each glyph to figure out the width of each fragment during layout, we can simultaneously gather data about the position of each glyph in the layout phase and utilize this information in the painting phase. I had to update expectations for a couple of reference tests. These updates are due to the fact that we now measure glyph positions during layout using a 1x font, and then linearly scale each glyph's position to device pixels during painting. This approach should be acceptable, considering we measure a fragment's width and height with an unscaled font during layout.
This commit is contained in:
parent
1a35621930
commit
681771d210
17 changed files with 65 additions and 42 deletions
|
@ -1422,7 +1422,7 @@ void Painter::draw_glyph_or_emoji(FloatPoint point, Utf8CodePointIterator& it, F
|
|||
draw_glyph(glyph.position, glyph.code_point, *glyph.font, color);
|
||||
} else {
|
||||
auto& emoji = draw_glyph_or_emoji.get<DrawEmoji>();
|
||||
draw_emoji(emoji.position, *emoji.emoji, *emoji.font);
|
||||
draw_emoji(emoji.position.to_type<int>(), *emoji.emoji, *emoji.font);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2445,7 +2445,7 @@ void Painter::draw_text_run(FloatPoint baseline_start, Utf8View const& string, F
|
|||
draw_glyph(glyph.position, glyph.code_point, *glyph.font, color);
|
||||
} else {
|
||||
auto& emoji = glyph_or_emoji.get<DrawEmoji>();
|
||||
draw_emoji(emoji.position, *emoji.emoji, *emoji.font);
|
||||
draw_emoji(emoji.position.to_type<int>(), *emoji.emoji, *emoji.font);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ DrawGlyphOrEmoji prepare_draw_glyph_or_emoji(FloatPoint point, Utf8CodePointIter
|
|||
// If we didn't find a text glyph, or have an emoji variation selector or regional indicator, try to draw an emoji glyph.
|
||||
if (auto const* emoji = Emoji::emoji_for_code_point_iterator(it)) {
|
||||
return DrawEmoji {
|
||||
.position = point.to_type<int>(),
|
||||
.position = point,
|
||||
.emoji = emoji,
|
||||
.font = &font,
|
||||
};
|
||||
|
@ -255,15 +255,4 @@ DrawGlyphOrEmoji prepare_draw_glyph_or_emoji(FloatPoint point, Utf8CodePointIter
|
|||
};
|
||||
}
|
||||
|
||||
Vector<DrawGlyphOrEmoji> get_glyph_run(FloatPoint baseline_start, Utf8View const& string, Font const& font, IncludeLeftBearing include_left_bearing)
|
||||
{
|
||||
Vector<DrawGlyphOrEmoji> glyphs_or_emojis;
|
||||
for_each_glyph_position(
|
||||
baseline_start, string, font, [&](auto glyph_or_emoji) {
|
||||
glyphs_or_emojis.append(glyph_or_emoji);
|
||||
},
|
||||
include_left_bearing);
|
||||
return glyphs_or_emojis;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ struct DrawGlyph {
|
|||
};
|
||||
|
||||
struct DrawEmoji {
|
||||
IntPoint position;
|
||||
FloatPoint position;
|
||||
Gfx::Bitmap const* emoji;
|
||||
Font const* font;
|
||||
};
|
||||
|
@ -92,7 +92,7 @@ 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)
|
||||
void for_each_glyph_position(FloatPoint baseline_start, Utf8View string, Font const& font, Callback callback, IncludeLeftBearing include_left_bearing = IncludeLeftBearing::No, Optional<float&> width = {})
|
||||
{
|
||||
float space_width = font.glyph_width(' ') + font.glyph_spacing();
|
||||
|
||||
|
@ -127,8 +127,9 @@ void for_each_glyph_position(FloatPoint baseline_start, Utf8View string, Font co
|
|||
point.translate_by(glyph_width, 0);
|
||||
last_code_point = code_point;
|
||||
}
|
||||
|
||||
if (width.has_value())
|
||||
*width = point.x() - font.glyph_spacing();
|
||||
}
|
||||
|
||||
Vector<DrawGlyphOrEmoji> get_glyph_run(FloatPoint baseline_start, Utf8View const& string, Font const& font, IncludeLeftBearing include_left_bearing = IncludeLeftBearing::No);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue