fix(ui-egui): the field editor sizes auto-size text as the page does

Review on #4862 found two mismatches between the on-page field editor and
the field's appearance:

- Comb fields: the editor sized them as single-line text (20.87 pt for a
  500 x 30 comb) while the appearance uses 4-12 pt from the cell height.
  The comb test is now `Field::is_comb` and the comb size
  `appearance::comb_auto_text_size`, both shared by the appearance and
  `forms_ui::field_text_size`. The editor's test was looser (it ignored
  Multiline and Password); it now matches the page's.
- Tall fields: `field_text_size` capped at 300 pt and the three call sites
  clamped the screen font to 64. Both are gone; `field_screen_font` scales
  by zoom and bounds the result at MAX_SCREEN_FONT (256 screen points) so a
  glyph stays well inside the font atlas.

A non-finite comb height now gives 4 pt, as single-line auto-size does.

Test: it::forms::the_field_editor_sizes_auto_size_text_as_the_page_does.
With the comb change reverted the comb assertion fails (20.87 vs 12); with
the 300/64 caps restored the 100 pt assertion fails.

Also fixes it::forms::dragging_over_another_fields_text_focuses_it_and_selects_from_the_press,
which the previous commit broke: the name field now auto-sizes to 13.9 pt
instead of 12, so the press point 30 px in fell on "A|da"; it is now 38 px
in, inside "Ad|a" as the test intends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
This commit is contained in:
KenM76
2026-10-26 19:27:44 -04:00
co-authored by Claude Opus 5.5
parent ccb2565036
commit 0e559fca41
5 changed files with 88 additions and 16 deletions
+10 -4
View File
@@ -56,6 +56,13 @@ pub fn auto_text_size(text: &str, width: f64, height: f64, multiline: bool, widt
)
}
/// The automatic font size of a comb field (`Field::is_comb`) whose cells are `height` tall inside
/// the padding: 4 to 12 pt, as only the height bounds a one-character cell. The page appearance
/// and the on-screen editor share this.
pub fn comb_auto_text_size(height: f64) -> f64 {
if height.is_finite() { (height / 1.15).clamp(4.0, 12.0) } else { 4.0 }
}
/// The tallest box single-line auto-size follows, as a sanity bound: the largest page side
/// ISO 32000-1 Annex C recommends.
pub(crate) const MAX_AUTO_HEIGHT: f64 = 14_400.0;
@@ -115,7 +122,7 @@ pub fn text_box(doc: &Document, f: &Field, w: &Widget) -> TextBox {
size: (da.size > 0.0 && da.size.is_finite()).then_some(da.size),
multiline,
password: f.has(flags::PASSWORD),
comb: f.has(flags::COMB) && !multiline && !f.has(flags::PASSWORD) && f.max_len.is_some_and(|m| m > 0),
comb: f.is_comb(),
}
}
@@ -819,7 +826,7 @@ fn field_appearance_fit(doc: &Document, f: &Field, w: &Widget, values: &[String]
}
}
_ => {
let comb = f.has(flags::COMB) && !f.has(flags::MULTILINE) && !f.has(flags::PASSWORD) && f.max_len.is_some_and(|m| m > 0);
let comb = f.is_comb();
if f.kind == FieldKind::Text && f.has(flags::MULTILINE) {
if size == 0.0 {
size = auto_text_size(&text, inner_w, height - 2.0 * pad, true, width_of);
@@ -846,9 +853,8 @@ fn field_appearance_fit(doc: &Document, f: &Field, w: &Widget, values: &[String]
}
} else {
if size == 0.0 {
// Comb cells hold one character each, so only the height limits them.
size = if comb {
((height - 2.0 * pad) / 1.15).clamp(4.0, 12.0)
comb_auto_text_size(height - 2.0 * pad)
} else {
auto_text_size(&text, inner_w, height - 2.0 * pad, false, width_of)
};
+6
View File
@@ -155,6 +155,12 @@ impl Field {
self.flags & flag != 0
}
/// A comb field: the Comb flag set with a `/MaxLen`, neither multiline nor password (ISO
/// 32000-2 Table 228). Each cell holds one character.
pub fn is_comb(&self) -> bool {
self.has(flags::COMB) && !self.has(flags::MULTILINE) && !self.has(flags::PASSWORD) && self.max_len.is_some_and(|m| m > 0)
}
pub fn read_only(&self) -> bool {
self.has(flags::READ_ONLY)
}