mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-21 08:48:57 +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;
|
Vector<DrawGlyph> glyph_run;
|
||||||
glyph_run.ensure_capacity(glyph_count);
|
glyph_run.ensure_capacity(glyph_count);
|
||||||
FloatPoint point = baseline_start;
|
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) {
|
for (size_t i = 0; i < glyph_count; ++i) {
|
||||||
auto position = point
|
auto position = point
|
||||||
- FloatPoint { 0, font.pixel_metrics().ascent }
|
- FloatPoint { 0, font.pixel_metrics().ascent }
|
||||||
+ FloatPoint { positions[i].x_offset, positions[i].y_offset } / text_shaping_resolution;
|
+ 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;
|
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
|
// 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 {
|
struct DrawGlyph {
|
||||||
FloatPoint position;
|
FloatPoint position;
|
||||||
u32 glyph_id;
|
size_t length_in_code_units { 0 };
|
||||||
|
float glyph_width { 0.0 };
|
||||||
void translate_by(FloatPoint const& delta)
|
u32 glyph_id { 0 };
|
||||||
{
|
|
||||||
position.translate_by(delta);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ShapeFeature {
|
typedef struct ShapeFeature {
|
||||||
|
|
|
@ -395,7 +395,10 @@ void InlineFormattingContext::generate_line_boxes()
|
||||||
glyphs.remove(last_glyph_index - 1, remove_item_count);
|
glyphs.remove(last_glyph_index - 1, remove_item_count);
|
||||||
glyphs.append(Gfx::DrawGlyph {
|
glyphs.append(Gfx::DrawGlyph {
|
||||||
.position = last_glyph_position,
|
.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