Graf de dependențe pentru calculul formularelor

HotPDF construiește un graf de dependențe peste câmpurile de calcul ale unui AcroForm încărcat, astfel încât o modificare de valoare recalculează doar calculele care o citesc tranzitiv, într-o ordine în care fiecare valoare recalculată este deja vizibilă calculelor care o consumă

Construirea grafului

THotPDF.BuildLoadedFormCalculationGraph returnează un instantaneu deținut de apelant. Fiecare câmp devine un nod; fiecare script Calculate înregistrat /CO este analizat static cu HPDFExtractSafeJavaScriptFieldReferences, care citește numele de câmp atinse de un script de subset sigur: argumentele între ghilimele ale AFSimple_Calculate("OP", ["a","b"]) și numele între ghilimele ale acceselor getField("x"), cu literalele de șir sărite, astfel încât mențiunile textuale nu sunt tratate ca referințe

THPDFFormCalcGraph.ResolveLinks rezolvă acele nume în muchii sursă → dependent și ordonează țintele cu o sortare topologică. Câmpurile aflate pe un ciclu de dependențe păstrează în schimb ordinea documentului /CO, potrivind semantica de o singură trecere a unei recalculări complete; un câmp modificat nu își recalculează niciodată propriul script, astfel încât ciclurile nu pot ping-pong, iar o valoare scrisă de utilizator câștigă întotdeauna. Numele de sursă care nu corespund niciunui câmp sunt raportate prin UnresolvedFieldNameCount și nu produc muchii, oglindind rezolvatorul runtime

Recalculare incrementală

RecalculateLoadedFormFieldsIncremental evaluează doar închiderea afectată a câmpurilor modificate date. Scrierile prin SetFormFieldValue și SetLoadedFormFieldValueByName acumulează un set murdar; supraîncărcarea fără parametri recalculează din acel set, astfel încât o importare FDF sau XFDF urmată de o trecere incrementală reîmprospătează fiecare calcul dependent fără a atinge cele necorelate. Ambele supraîncărcări și trecerea completă RecalculateLoadedFormFields consumă setul murdar după aceea

PDF.LoadFromFile('Order.pdf');
PDF.SetLoadedFormFieldValueByName('qty', '3');
PDF.SetLoadedFormFieldValueByName('price', '19.5');
// Recomputes subtotal and total only, chained in one pass
PDF.RecalculateLoadedFormFieldsIncremental(['qty', 'price']);

Inspectarea grafului

Graful expune starea de calcul per câmp (GetNode), secvența completă de evaluare (AllTargets), închiderea afectată (AffectedTargets), numărul de ținte aflate pe cicluri (CyclicTargetCount) și numele de sursă nerezolvate, astfel încât instrumentele pot previzualiza exact ce calcule va declanșa o editare