fix(canvas): resolve named draw family in caret measurement

Implement Painter::measure_text_family on the native skia backend
(NativeBackend::measure_text_family_styled segments per-codepoint
against the real family, exactly like draw_text) and forward it through
NativeFrameBackend + BaselineAdjustingBackend so the family-aware
measure reaches skia through the wrappers. Fixes the ~6px caret drift
in every TextInputView/TextArea chrome input (property pills, chat, git,
settings) — measure now uses the same typeface paint does.

Bumps vendor/jian to 19fb00b (Painter::measure_text_family).
This commit is contained in:
Kayshen-X 2026-06-20 20:29:41 +08:00
parent e1f13d2afb
commit 0c2af63b4e
4 changed files with 33 additions and 2 deletions

View file

@ -267,4 +267,8 @@ impl RenderBackend for BaselineAdjustingBackend<'_> {
self.inner
.measure_text_styled(text, font_size, weight, italic)
}
fn measure_text_family(&mut self, text: &str, font_size: f32, family: &str) -> f32 {
self.inner.measure_text_family(text, font_size, family)
}
}

View file

@ -284,4 +284,8 @@ impl<'a> RenderBackend for NativeFrameBackend<'a> {
self.inner
.measure_text_styled(text, font_size, weight, italic)
}
fn measure_text_family(&mut self, text: &str, font_size: f32, family: &str) -> f32 {
self.inner.measure_text_family(text, font_size, family)
}
}

View file

@ -249,7 +249,24 @@ impl NativeBackend {
weight: u16,
italic: bool,
) -> f32 {
let segments = self.segment_text_styled(text, "", weight, italic);
self.measure_text_family_styled(text, font_size, "", weight, italic)
}
/// Like [`Self::measure_text_styled`] but resolves the per-codepoint
/// typeface against `family` — exactly as `draw_text` does for a run
/// carrying that family. The family-blind `measure_text*` pass `""`
/// (bundled Roboto); chrome inputs that DRAW in a named family (e.g.
/// "Inter") must measure with that same family so their caret /
/// selection geometry lines up with the painted glyphs.
pub fn measure_text_family_styled(
&mut self,
text: &str,
font_size: f32,
family: &str,
weight: u16,
italic: bool,
) -> f32 {
let segments = self.segment_text_styled(text, family, weight, italic);
if segments.is_empty() {
return 0.0;
}
@ -262,6 +279,12 @@ impl NativeBackend {
advance
}
/// Family-aware width at the default weight/upright — the measurement
/// backing `Painter::measure_text_family` for caret positioning.
pub fn measure_text_family(&mut self, text: &str, font_size: f32, family: &str) -> f32 {
self.measure_text_family_styled(text, font_size, family, 400, false)
}
/// Render every shaped run in the layout via cached typefaces +
/// `Canvas::draw_str` (Step 4 perf fix — see comment on the
/// `typeface` / `cjk_typeface` fields).

2
vendor/jian vendored

@ -1 +1 @@
Subproject commit ce19bed8a086cd18541c4715cdc308a2cfb5e2fb
Subproject commit 19fb00ba88a5be0e15f7d2b5468337cdb0037984