mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-20 16:28:54 +00:00
LibGfx+LibWeb: Add some extra fields to glyph run data
We currently have a mixup in LibWeb between code unit offset and glyph offset during hit testing. These extra fields will allow us to correct this discrepency.
This commit is contained in:
parent
b1fe816336
commit
047f521c4c
Notes:
github-actions[bot]
2025-08-22 12:08:06 +00:00
Author: https://github.com/trflynn89
Commit: 047f521c4c
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5930
3 changed files with 33 additions and 8 deletions
|
@ -110,11 +110,36 @@ NonnullRefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spaci
|
|||
Vector<DrawGlyph> glyph_run;
|
||||
glyph_run.ensure_capacity(glyph_count);
|
||||
FloatPoint point = baseline_start;
|
||||
|
||||
// We track the code unit length rather than just the code unit offset because LibWeb may later collapse glyph runs.
|
||||
// Updating the offset of each glyph gets tricky when handling text direction (LTR/RTL). So rather than doing that,
|
||||
// we just provide the glyph's code unit length and base LibWeb algorithms on that.
|
||||
//
|
||||
// A single grapheme may be represented by multiple glyphs, where any of those glyphs are zero-width. We want to
|
||||
// assign code unit lengths such that each glyph knows the length of the text it respresents.
|
||||
auto glyph_length_in_code_units = [&](auto index) -> size_t {
|
||||
auto starting_offset = glyph_info[index].cluster;
|
||||
|
||||
for (size_t i = index + 1; i < glyph_count; ++i) {
|
||||
if (auto offset = glyph_info[i].cluster; offset != starting_offset)
|
||||
return offset - starting_offset;
|
||||
}
|
||||
|
||||
return string.length_in_code_units() - starting_offset;
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < glyph_count; ++i) {
|
||||
auto position = point
|
||||
- FloatPoint { 0, font.pixel_metrics().ascent }
|
||||
+ FloatPoint { positions[i].x_offset, positions[i].y_offset } / text_shaping_resolution;
|
||||
glyph_run.unchecked_append({ position, glyph_info[i].codepoint });
|
||||
|
||||
glyph_run.unchecked_append({
|
||||
.position = position,
|
||||
.length_in_code_units = glyph_length_in_code_units(i),
|
||||
.glyph_width = positions[i].x_advance / text_shaping_resolution,
|
||||
.glyph_id = glyph_info[i].codepoint,
|
||||
});
|
||||
|
||||
point += FloatPoint { positions[i].x_advance, positions[i].y_advance } / text_shaping_resolution;
|
||||
|
||||
// NOTE: The spec says that we "really should not" apply letter-spacing to the trailing edge of a line but
|
||||
|
|
|
@ -20,12 +20,9 @@ namespace Gfx {
|
|||
|
||||
struct DrawGlyph {
|
||||
FloatPoint position;
|
||||
u32 glyph_id;
|
||||
|
||||
void translate_by(FloatPoint const& delta)
|
||||
{
|
||||
position.translate_by(delta);
|
||||
}
|
||||
size_t length_in_code_units { 0 };
|
||||
float glyph_width { 0.0 };
|
||||
u32 glyph_id { 0 };
|
||||
};
|
||||
|
||||
typedef struct ShapeFeature {
|
||||
|
|
|
@ -395,7 +395,10 @@ void InlineFormattingContext::generate_line_boxes()
|
|||
glyphs.remove(last_glyph_index - 1, remove_item_count);
|
||||
glyphs.append(Gfx::DrawGlyph {
|
||||
.position = last_glyph_position,
|
||||
.glyph_id = glyph_run->font().glyph_id_for_code_point(ellipsis_codepoint) });
|
||||
.length_in_code_units = AK::UnicodeUtils::code_unit_length_for_code_point(ellipsis_codepoint),
|
||||
.glyph_width = glyph_run->font().glyph_width(ellipsis_codepoint),
|
||||
.glyph_id = glyph_run->font().glyph_id_for_code_point(ellipsis_codepoint),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue