mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-28 12:08:46 -06:00
Opening a static XFA form gives its fields the values in its datasets (a form filled in by another application). Each value went through forms::set_value, which reads the whole field tree to find the field, writes it, and recalculates, reading the tree again. With n values that is about 2n readings of n fields: quadratic. A public 136-page form with about 6,000 fields took 261 s to open, a 95-page one with about 4,000 took 112 s; 8,000 synthetic fields took over ten minutes. forms::set_values fills a batch as set_value fills each in turn, reading the form once and recalculating once after the last value (the calculation order, ISO 32000-2 Table 224 /CO, runs once over the final values). Fields with the same fully qualified name (12.7.4.2) still share the value. A name the batch already wrote, or a twin of it, makes the form be read again first, so each write starts from what the earlier one left, as one by one. Each value reports its own result; a failed recalculation fails the batch, as it fails set_value. The engine collects the changed values and fills them with set_values, finding fields by name through a map rather than a scan. The two forms now open in 4 s and 3 s, with the same fields, values, warnings and document information as before; 8,000 synthetic fields open in 1.5 s. Tests: set_values matches set_value one by one (values, twins, the calculated total, every appearance, saved; refusals for an unknown name, a read-only field, an unknown option and clearing a no-toggle-off radio group the batch selected); it reads the form a fixed number of times; the engine takes 59 data values on a 60-field static form exactly as filling them one by one does (the read-only one refused); and opening 800 fields takes under 16 times as long as 100 (about 4x now, about 48x before). Claude-Session: https://claude.ai/code/session_01CBVyQEwtmEw3mS1MoAiwrK Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>