mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-29 04:28:20 -06:00
add_field gave text and date fields a fixed /Helv 12 Tf, which is clipped in a box shorter than 12 pt, and a script can't see the clipping. They now get /Helv 0 Tf (Auto), as Acrobat's new text fields do: 12 pt where there is room, smaller where there isn't. An explicit size set afterwards still wins; choice fields keep 12 pt. Claude-Session: https://claude.ai/code/session_01RUNQSPVXx3dDBabRZHAnjz Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
1ae12090d0
commit
8248379152
@@ -1,8 +1,9 @@
|
||||
//! Prepare a form: create, change and delete fields (execution plan M6.6).
|
||||
//!
|
||||
//! New fields follow Acrobat's conventions: names "Text1", "Check Box1", "Group1" (radio groups),
|
||||
//! "Dropdown1", "List Box1", "Button1", "Signature1", "Date1"; 12 pt Helvetica (auto-size for
|
||||
//! check boxes), a thin grey border and a white background, and appearance streams generated
|
||||
//! "Dropdown1", "List Box1", "Button1", "Signature1", "Date1"; Helvetica at Acrobat's Auto size
|
||||
//! for text and date fields (12 pt in a box that has room, smaller in a short one), 12 pt in
|
||||
//! choice fields, a thin grey border and a white background, and appearance streams generated
|
||||
//! immediately so every viewer shows the empty field.
|
||||
|
||||
use pdfcraft_cos::{Dict, Document, ObjRef, Object, PdfString, Stream};
|
||||
@@ -545,14 +546,15 @@ pub fn add_field(doc: &mut Document, page: usize, rect: [f64; 4], kind: &NewFiel
|
||||
match kind {
|
||||
NewField::Text { multiline } => {
|
||||
w.set(b"FT".to_vec(), Object::name("Tx"));
|
||||
w.set(b"DA".to_vec(), PdfString::literal(b"/Helv 12 Tf 0 g".to_vec()));
|
||||
// Auto size (0): a fixed 12 pt is clipped in a box shorter than that (#1888).
|
||||
w.set(b"DA".to_vec(), PdfString::literal(b"/Helv 0 Tf 0 g".to_vec()));
|
||||
if *multiline {
|
||||
w.set(b"Ff".to_vec(), Object::Int(flags::MULTILINE as i64));
|
||||
}
|
||||
}
|
||||
NewField::Date => {
|
||||
w.set(b"FT".to_vec(), Object::name("Tx"));
|
||||
w.set(b"DA".to_vec(), PdfString::literal(b"/Helv 12 Tf 0 g".to_vec()));
|
||||
w.set(b"DA".to_vec(), PdfString::literal(b"/Helv 0 Tf 0 g".to_vec()));
|
||||
// Acrobat's format and keystroke actions for mm/dd/yyyy (run by its JavaScript engine).
|
||||
let js = |s: &str| {
|
||||
let mut a = Dict::new();
|
||||
|
||||
@@ -895,6 +895,34 @@ fn formats_validation_and_calculations_run_like_acrobat() {
|
||||
assert_eq!(field(&fields(&doc), "Price").actions.format, Format::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_text_fields_fit_their_box() {
|
||||
// #1888: a fixed 12 pt was clipped in a short box. New text and date fields take Acrobat's
|
||||
// Auto size: 12 pt where there is room, smaller where there isn't.
|
||||
let mut doc = one_page();
|
||||
let tf_size = |ap: &str| {
|
||||
ap.split("/Helv ")
|
||||
.nth(1)
|
||||
.and_then(|s| s.split(' ').next())
|
||||
.and_then(|n| n.parse::<f64>().ok())
|
||||
.unwrap_or_else(|| panic!("no /Helv size in {ap}"))
|
||||
};
|
||||
for (kind, name, value) in [(NewField::Text { multiline: false }, "short", "Hello world"), (NewField::Date, "date", "10/13/2026")] {
|
||||
add_field(&mut doc, 0, [20.0, 20.0, 200.0, 28.0], &kind, Some(name)).unwrap();
|
||||
set_value(&mut doc, name, &FieldValue::Text(value.into())).unwrap();
|
||||
let f = field(&fields(&doc), name).clone();
|
||||
assert_eq!(f.da, "/Helv 0 Tf 0 g", "{name}");
|
||||
let size = tf_size(&ap(&doc, &f.widgets[0]));
|
||||
assert!(size > 0.0 && size <= 8.0, "{name}: {size} pt in an 8 pt box");
|
||||
}
|
||||
add_field(&mut doc, 0, [20.0, 50.0, 200.0, 72.0], &NewField::Text { multiline: false }, Some("tall")).unwrap();
|
||||
set_value(&mut doc, "tall", &FieldValue::Text("Hello world".into())).unwrap();
|
||||
assert_eq!(tf_size(&ap(&doc, &field(&fields(&doc), "tall").widgets[0])), 12.0, "a box with room keeps the 12 pt look");
|
||||
// An explicit size still wins.
|
||||
set_props(&mut doc, "short", &FieldProps { font_size: Some(12.0), ..FieldProps::default() }).unwrap();
|
||||
assert_eq!(tf_size(&ap(&doc, &field(&fields(&doc), "short").widgets[0])), 12.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn appearance_properties_restyle_every_widget() {
|
||||
let mut doc = one_page();
|
||||
|
||||
Reference in New Issue
Block a user