폼 계산 의존성 그래프

HotPDF는 로드된 AcroForm의 계산 필드 위에 의존성 그래프를 구축하여 값 변경 시 이를 전이적으로 읽는 계산만 재계산하되, 각 재계산 값이 이를 소비하는 계산에 이미 보이도록 정렬합니다

그래프 구축

THotPDF.BuildLoadedFormCalculationGraph은 호출자가 소유한 스냅샷을 반환합니다. 모든 필드는 노드가 됩니다. 각 /CO 등록 Calculate 스크립트는 HPDFExtractSafeJavaScriptFieldReferences로 정적으로 분석되며, 이는 안전 부분집합 스크립트가 접촉하는 필드 이름을 읽습니다. 즉 AFSimple_Calculate("OP", ["a","b"])의 따옴표 인수와 getField("x") 접근의 따옴표 이름이며, 문자열 리터럴은 건너뛰므로 텍스트 언급이 참조로 취급되지 않습니다

THPDFFormCalcGraph.ResolveLinks은 그 이름을 source → dependent 엣지로 해결하고 위상 정렬로 대상을 정렬합니다. 의존성 주기의 필드는 대신 /CO 문서 순서를 유지하여 전체 재계산의 one-pass 의미론과 일치시킵니다. 변경된 필드는 자신의 스크립트를 절대 재계산하지 않으므로 주기가 ping-pong이 되지 않고 사용자 작성 값이 항상 우선합니다. 필드와 일치하지 않는 소스 이름은 UnresolvedFieldNameCount로 보고되고 엣지를 만들지 않으며, 이는 런타임 해석기를 반영합니다

증분 재계산

RecalculateLoadedFormFieldsIncremental은 주어진 변경된 필드의 영향 폐포만 평가합니다. SetFormFieldValue와 SetLoadedFormFieldValueByName을 통한 쓰기는 더티 집합을 누적하며, 매개변수 없는 오버로드는 그 집합에서 재계산하므로 FDF 또는 XFDF 가져오기 후 증분 패스 하나가 관련 없는 것을 건드리지 않고 모든 의존 계산을 갱신합니다. 두 오버로드와 전체 RecalculateLoadedFormFields 패스는 이후 더티 집합을 소비합니다

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

그래프 검사

그래프는 필드별 계산 상태(GetNode), 전체 평가 시퀀스(AllTargets), 영향 폐포(AffectedTargets), 주기의 대상 수(CyclicTargetCount), 해결되지 않은 소스 이름을 노출하므로 도구가 편집이 정확히 어떤 계산을 트리거할지 미리 볼 수 있습니다