Grafo de dependência de cálculo de formulário

O HotPDF constrói um grafo de dependência sobre os campos de cálculo de um AcroForm carregado para que uma mudança de valor recalcule apenas os cálculos que a leem transitivamente, em uma ordem em que cada valor recomputado já está visível para os cálculos que o consomem

Construção do grafo

THotPDF.BuildLoadedFormCalculationGraph retorna um instantâneo de propriedade do chamador. Cada campo se torna um nó; cada script Calculate registrado em /CO é analisado estaticamente com HPDFExtractSafeJavaScriptFieldReferences, que lê os nomes de campo que um script de subconjunto seguro toca: os argumentos entre aspas de AFSimple_Calculate("OP", ["a","b"]) e os nomes entre aspas de acessos getField("x"), com literais de string ignorados para que menções textuais não sejam tratadas como referências

THPDFFormCalcGraph.ResolveLinks resolve esses nomes em arestas source → dependent e ordena os destinos com uma ordenação topológica. Campos em um ciclo de dependência mantêm a ordem de documento /CO em vez disso, correspondendo à semântica de uma única passagem de um recálculo completo; um campo alterado nunca recalcula seu próprio script, então ciclos não podem pingar e um valor escrito pelo usuário sempre vence. Nomes de origem que não correspondem a nenhum campo são relatados por meio de UnresolvedFieldNameCount e não produzem arestas, espelhando o resolvedor de runtime

Recálculo incremental

RecalculateLoadedFormFieldsIncremental avalia apenas o fechamento afetado dos campos alterados fornecidos. Gravações por meio de SetFormFieldValue e SetLoadedFormFieldValueByName acumulam um conjunto sujo; a sobrecarga sem parâmetros recalcula a partir desse conjunto, de modo que uma importação FDF ou XFDF seguida por uma passagem incremental atualiza cada cálculo dependente sem tocar nos não relacionados. Ambas as sobrecargas e a passagem completa de RecalculateLoadedFormFields consomem o conjunto sujo depois

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']);

Inspeção do grafo

O grafo expõe estado de cálculo por campo (GetNode), a sequência completa de avaliação (AllTargets), o fechamento afetado (AffectedTargets), o número de destinos em ciclos (CyclicTargetCount) e nomes de origem não resolvidos, para que ferramentas possam pré-visualizar exatamente quais cálculos uma edição disparará