Teknisk artikel

HotPDF: object streams and incremental updates in Delphi

HotPDF är ett nativt VCL PDF-bibliotek för Delphi- och C++Builder-program som behöver direkt PDF-skapande och redigering, formulär, annoteringar, kryptering, digitala signaturer, Unicode-teckensnitt, standardmedveten utdata och preflight-rapporter utan extern PDF-runtime.

Den här artikeln är skriven för engineers maintaining PDFs that may already contain signatures, revisions, compressed objects, or repair history. Den behandlar object streams and incremental updates som produktionsnära dokumentteknik, inte som ett isolerat komponentanrop.

Den praktiska risken är att rewriting a file as if it were newly generated can discard revision history, break signatures, or hide damaged cross-reference data. Därför behöver flödet ett skrivet kontrakt, observerbar diagnostik och realistiska regressionsfiler.

Arkitekturbeslut

Understand the existing revision chain. whether existing signatures or audit trails must remain valid / policy for object stream preservation, decompression, or recompression

  • whether existing signatures or audit trails must remain valid
  • policy for object stream preservation, decompression, or recompression
  • repair handling when cross-reference data is inconsistent
  • metadata and catalog updates that should be appended instead of rewritten

Implementeringsflöde

Choose full rewrite or incremental save deliberately. Ordningen nedan gör arbetsflödet granskbart för Delphi- och C++Builder-team.

  1. inspect the source for signatures, xref streams, object streams, and prior revisions
  2. select incremental update only when the business goal requires preservation
  3. write changed objects to a new revision and leave untouched objects stable
  4. verify signatures, object counts, and cross-reference consistency after saving
  5. record the reason if a full rewrite was required for repair or normalization

Valideringsbevis

Revision evidence to capture. Behåll dessa fält tillsammans med utdata eller supportunderlaget.

  • source revision count, signature presence, xref style, and object stream count
  • save mode, changed object identifiers, and whether object streams were preserved
  • validator output before and after the update
  • signature status for every signed revision after the final file is written

Compressed objects change support diagnostics

Object streams, hybrid cross-reference tables, and incremental saves are normal in modern PDFs. The workflow should know whether it is preserving a revision, appending a new revision, or creating a clean output file.

Review questions before release

Before this reaches production, the team should be able to answer these questions without reading source code.

  • Who owns whether existing signatures or audit trails must remain valid?
  • What evidence proves source revision count, signature presence, xref style, and object stream count?
  • What happens when a full rewrite can invalidate signatures even when visible content is unchanged?
  • Which regression file covers record the reason if a full rewrite was required for repair or normalization?

Tekniska granskningsnoteringar för object streams and incremental updates

Använd dessa granskningsnoteringar för att säkerställa att funktionen har passerat demo-nivån och kan försvaras under leverans, support och kundeskalering.

  • Beslut: whether existing signatures or audit trails must remain valid. Implementeringspresspunkt: select incremental update only when the business goal requires preservation. Acceptansbevis: validator output before and after the update. Regressionsutlösare: object-stream compression can make diff-based support investigations misleading
  • Beslut: policy for object stream preservation, decompression, or recompression. Implementeringspresspunkt: write changed objects to a new revision and leave untouched objects stable. Acceptansbevis: signature status for every signed revision after the final file is written. Regressionsutlösare: a full rewrite can invalidate signatures even when visible content is unchanged
  • Beslut: repair handling when cross-reference data is inconsistent. Implementeringspresspunkt: verify signatures, object counts, and cross-reference consistency after saving. Acceptansbevis: source revision count, signature presence, xref style, and object stream count. Regressionsutlösare: repairing a damaged file may require a support note explaining lost revisions
  • Beslut: metadata and catalog updates that should be appended instead of rewritten. Implementeringspresspunkt: record the reason if a full rewrite was required for repair or normalization. Acceptansbevis: save mode, changed object identifiers, and whether object streams were preserved. Regressionsutlösare: linearization can be lost after incremental updates unless the workflow rebuilds it
  • Beslut: whether existing signatures or audit trails must remain valid. Implementeringspresspunkt: inspect the source for signatures, xref streams, object streams, and prior revisions. Acceptansbevis: validator output before and after the update. Regressionsutlösare: object-stream compression can make diff-based support investigations misleading
  • Beslut: policy for object stream preservation, decompression, or recompression. Implementeringspresspunkt: select incremental update only when the business goal requires preservation. Acceptansbevis: signature status for every signed revision after the final file is written. Regressionsutlösare: a full rewrite can invalidate signatures even when visible content is unchanged
  • Beslut: repair handling when cross-reference data is inconsistent. Implementeringspresspunkt: write changed objects to a new revision and leave untouched objects stable. Acceptansbevis: source revision count, signature presence, xref style, and object stream count. Regressionsutlösare: repairing a damaged file may require a support note explaining lost revisions

Gränsfall

  • a full rewrite can invalidate signatures even when visible content is unchanged
  • repairing a damaged file may require a support note explaining lost revisions
  • linearization can be lost after incremental updates unless the workflow rebuilds it
  • object-stream compression can make diff-based support investigations misleading

Delphi / C++Builder notes

HotPDF Component should sit behind a small service boundary that receives files, streams, profiles, and credentials, then returns output paths, warnings, metrics, and validation status. Important terms include object stream, incremental update, xref stream, revision, signature preservation, repair.

Delphi-kodexempel

Följande Delphi-skiss visar en praktisk servicegräns för detta ämne. Håll policykontroller, loggning och validering utanför det smala produktanropet så att arbetsflödet går att testa.

procedure SaveCompactIncrementalPdf(const OutputFile: string);
var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := OutputFile;
    Pdf.UseXRefStream := True;
    Pdf.UseObjectStreams := True;
    Pdf.BeginDoc;
    AddRevisionContent(Pdf);
    Pdf.EndDoc;
    CompareObjectStreamProfile(OutputFile);
  finally
    Pdf.Free;
  end;
end;

Produktionschecklista

  • Kör arbetsflödet på en tom fil, en normal kundfil och en värstafallfil
  • Öppna den genererade PDF-filen med rätt visare, validator, skrivare eller nedströmsapplikation
  • Logga produktversion, profilversion, inmatningshash, utdatasökväg, förfluten tid och antal varningar
  • Håll lösenord, certifikat, tillfälliga filer och kunddata under tydliga lagringsregler
  • Lägg till regressionsdokument när en kundfil avslöjar ett nytt gränsfall

Produktdokumentation

HotPDF Component

Fler kodexempel

Pdf.BeginIncrementalUpdate('contract-signed.pdf');
Pdf.AddPage;
Pdf.CurrentPage.SetFont('Arial', [], 10);
Pdf.CurrentPage.TextOut(50, 760, 0, 'Addendum recorded 2026-06-11');
Pdf.SaveIncrementalUpdate('contract-updated.pdf');  // appends the delta only
PageCount := Pdf.LoadFromFile('base.pdf');
Pdf.InsertPagesFromDocument(OtherDoc, '1-3', 5);  // pages 1-3 after page 5
Pdf.MovePage(2, 5);
Pdf.SaveLoadedDocument('modified.pdf');
Pdf.LoadFromFile('stamped.pdf');
Pdf.SaveLoadedDocument('compacted.pdf');