Form Calculation Dependency Graph
HotPDF construit un graphe de dépendances sur les champs de calcul d'un AcroForm chargé afin qu'un changement de valeur ne recalcule que les calculs qui le lisent transitivement, dans un ordre où chaque valeur recalculée est déjà visible pour les calculs qui la consomment
Construction du graphe
THotPDF.BuildLoadedFormCalculationGraph renvoie un instantané possédé par l'appelant. Chaque champ devient un nœud ; chaque script Calculate enregistré via /CO est analysé statiquement avec HPDFExtractSafeJavaScriptFieldReferences, qui lit les noms de champs qu'un script de sous-ensemble sûr touche : les arguments entre guillemets de AFSimple_Calculate("OP", ["a","b"]) et les noms entre guillemets des accès getField("x"), les littéraux de chaînes étant ignorés afin que les mentions textuelles ne soient pas traitées comme des références
THPDFFormCalcGraph.ResolveLinks résout ces noms en arêtes source → dépendant et ordonne les cibles avec un tri topologique. Les champs sur un cycle de dépendances conservent l'ordre documentaire /CO à la place, correspondant à la sémantique monotache d'un recalcul complet ; un champ modifié ne recalcule jamais son propre script, de sorte que les cycles ne peuvent pas rebondir et qu'une valeur écrite par l'utilisateur gagne toujours. Les noms sources qui ne correspondent à aucun champ sont signalés via UnresolvedFieldNameCount et ne produisent aucune arête, reflétant le résolveur d'exécution
Recalcul incrémental
RecalculateLoadedFormFieldsIncremental n'évalue que la fermeture affectée des champs modifiés donnés. Les écritures via SetFormFieldValue et SetLoadedFormFieldValueByName accumulent un ensemble sale ; la surcharge sans paramètre recalcule à partir de cet ensemble, de sorte qu'un import FDF ou XFDF suivi d'un passage incrémental actualise chaque calcul dépendant sans toucher aux non associés. Les deux surcharges et le RecalculateLoadedFormFields complet consomment l'ensemble sale par la suite
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']);
Inspection du graphe
Le graphe expose l'état de calcul par champ (GetNode), la séquence d'évaluation complète (AllTargets), la fermeture affectée (AffectedTargets), le nombre de cibles sur cycles (CyclicTargetCount) et les noms sources non résolus, afin que les outils puissent prévisualiser exactement quels calculs une modification déclenchera