Sample code for 30+ languages & platforms
Lazarus Pascal Requires Chilkat v11.7.0+

Replace Text in a Signed PDF (PreserveSignatures)

See more PDF Text Replacement Examples

Applying a text replacement rewrites the page content, which invalidates any digital signature on the PDF. While the PreserveSignatures property is true (the default), "apply" is refused on a signed PDF; "check" only reads and is always allowed. Setting PreserveSignatures to false allows the replacement; the signature field stays in the written PDF but no longer verifies, so the document should be signed again afterwards if a signature is wanted.

Chilkat Lazarus Pascal Downloads

Lazarus Pascal
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.Pdf,
  Chilkat.JsonObject;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  pdf: TPdf;
  json: TJsonObject;
  jsonOut: TJsonObject;
  sigInfo: TJsonObject;
  validated: Boolean;

begin
  success := False;

  //  This example requires the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  //  The PDF used in this example is available at invoice_signed.pdf

  pdf := TPdf.Create;
  success := pdf.LoadFile('qa_data/pdf/invoice_signed.pdf');
  if (success = False) then
    begin
      WriteLn(pdf.LastErrorText);
      Exit;
    end;
  WriteLn('Signatures: ' + pdf.NumSignatures);

  json := TJsonObject.Create;
  json.UpdateString('labels[0].label','Invoice Number:');
  json.UpdateString('labels[0].value','INV-2026-0500');

  //  "check" reads only, so it works on a signed PDF.
  jsonOut := TJsonObject.Create;
  success := pdf.TextReplace('check',json,jsonOut);
  if (success = False) then
    begin
      WriteLn(pdf.LastErrorText);
      Exit;
    end;
  WriteLn('check: ok = ' + jsonOut.BoolOf('ok'));

  //  "apply" is refused while PreserveSignatures is true (the default).
  success := pdf.TextReplace('apply',json,jsonOut);
  if (success = False) then
    begin
      WriteLn('apply refused: ' + pdf.LastErrorText);
    end;

  //  Allowing the signature to be broken:
  pdf.PreserveSignatures := False;
  success := pdf.TextReplace('apply',json,jsonOut);
  if (success = False) then
    begin
      WriteLn(pdf.LastErrorText);
      Exit;
    end;
  WriteLn('applied: ' + jsonOut.BoolOf('applied'));

  //  The written PDF is a full rewrite with the replacement.  The signature field is still in the document,
  //  but the bytes it signed are gone, so it no longer verifies.
  success := pdf.WriteFile('qa_output/invoice_reissued_broken_signature.pdf');
  if (success = False) then
    begin
      WriteLn(pdf.LastErrorText);
      Exit;
    end;
  WriteLn('Signatures after writing: ' + pdf.NumSignatures);
  sigInfo := TJsonObject.Create;
  validated := pdf.VerifySignature(0,sigInfo);
  WriteLn('Signature 0 verifies: ' + validated);

  //  Sample output:

  //  Signatures: 1
  //  check: ok = true
  //  apply refused: ChilkatLog:
  //    TextReplace:
  //      DllDate: Nov  7 2026
  //      ChilkatVersion: 11.7.0
  //      UnlockPrefix: CHLKAT
  //      UnlockStatus: 2
  //      Architecture: Little Endian; 64-bit
  //      Language: Visual C++ 11.0 / x64
  //      VerboseLogging: 0
  //      replaceTextOp:
  //        op: apply
  //        The PDF is signed: replacing text rewrites the content and invalidates the signatures (set PreserveSignatures = false to allow it).
  //      --replaceTextOp
  //      Failed.
  //    --TextReplace
  //  --ChilkatLog
  //  
  //  applied: true
  //  Signatures after writing: 1
  //  Signature 0 verifies: false


  pdf.Free;
  json.Free;
  jsonOut.Free;
  sigInfo.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.