mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-31 21:48:09 -06:00
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:
co-authored by
Claude Opus 5.5
parent
ccb2565036
commit
0e559fca41
@@ -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)
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user