Examples / signature_ap / activex_cpp

Signature Ap

A complete, runnable activex_cpp program — 99 lines, shipped in your download.

Demonstrates Digital Signatures

Same example, other languages: c cpp cpp_linux csharp python vbnet

examples/activex_cpp/signature_ap/signature_ap.cpp 99 lines
// ============================================================================
//  signature_ap -- C++ ActiveX (COM) port, following
//  examples/activex/signature_ap/signature_ap.vbs
//
//  Builds a signature field with a CUSTOM APPEARANCE drawn using ordinary PDF
//  operators -- two axial shadings clipped to a rectangle and an ellipse, plus
//  text -- and then signs the file with a self-signed certificate.
//
//  CreateSigFieldAP opens an appearance TEMPLATE; everything between it and
//  EndTemplate is drawn into that template, not onto the page. The validation
//  icon is placed BEFORE the appearance is created: its unscaled size is always
//  100x100 units and it must sit fully inside the template.
// ============================================================================
#import "..\\..\\wrappers\\activex\\LumasPdfAX.tlb" no_namespace named_guids

#include <windows.h>

#include "axcommon.h"

#include <cstdio>
#include <string>

// NO_COLOR is a type-library enumerator; local re-declaration is C2365.

// The engine's colour order is 0x00BBGGRR, which is what r + g*256 + b*65536 is.
static long RGBv(long r, long g, long b) { return r + g * 256 + b * 65536; }

int main() {
    ChdirToExe();
    ComInit com;
    if (!com.ok()) return 1;

    ILumasPDFPtr pdf;
    if (FAILED(pdf.CreateInstance(L"LumasPdf.PDF"))) return 1;
    pdf->RaiseExceptions = VARIANT_FALSE;

    pdf->CreateNewPDFW(B(""));

    pdf->Append();
    pdf->SetFontW(B("Arial"), fsNone, 14, VARIANT_TRUE, cp1252);
    std::string body =
        "This file is digitally signed with a self sign certificate. "
        "The appearance of the signature field is created with normal PDF functions. However, it "
        "would also be possible to import a PDF page, an EMF file, or an image into the "
        "appearance template.";
    body += '\n'; body += '\n';
    body +=
        "When creating an individual signature appearance make sure to place the validation icon "
        "properly with PlaceSigFieldValidateIcon(). The unscaled size of that icon is always "
        "100.0 x 100.0 Units and it must be placed fully inside the appearance template.";
    pdf->WriteFTextW(taLeft, B(body));

    long sigField = pdf->CreateSigField(B("Signature"), -1, 200, 500, 200, 80);
    pdf->SetFieldColor(sigField, fcBorderColor, csDeviceRGB, NO_COLOR);
    pdf->PlaceSigFieldValidateIcon(sigField, 0, 15, 50, 50);
    pdf->CreateSigFieldAP(sigField);

    pdf->SaveGraphicState();
    pdf->Rectangle(0, 0, 200, 80, fmNoFill);
    pdf->ClipPath(cmWinding, fmNoFill);
    long sh = pdf->CreateAxialShading(0, 0, 200, 0, 0.5, RGBv(120, 120, 220),
                                      RGBv(255, 255, 255), VARIANT_TRUE, VARIANT_TRUE);
    pdf->ApplyShading(sh);
    pdf->RestoreGraphicState();

    pdf->SaveGraphicState();
    pdf->Ellipse(50.5, 1, 148.5, 78, fmNoFill);
    pdf->ClipPath(cmWinding, fmNoFill);
    sh = pdf->CreateAxialShading(0, 0, 0, 78, 2, RGBv(255, 255, 255),
                                 RGBv(120, 120, 220), VARIANT_TRUE, VARIANT_TRUE);
    pdf->ApplyShading(sh);
    pdf->RestoreGraphicState();

    pdf->SetFontW(B("Arial"), fsBold | fsUnderlined, 11, VARIANT_TRUE, cp1252);
    pdf->SetFillColor(RGBv(120, 120, 220));
    pdf->WriteFTextExW(50, 60, 150, -1, taCenter, B("Digitally signed by:"));
    pdf->SetFontW(B("Arial"), fsBold | fsItalic, 18, VARIANT_TRUE, cp1252);
    pdf->SetFillColor(RGBv(100, 100, 200));
    pdf->WriteFTextExW(50, 45, 150, -1, taCenter, B("LumasPdf"));

    pdf->EndTemplate();
    pdf->EndPage();

    std::string outFile = OutFile();
    if (pdf->HaveOpenDoc())
        if (!pdf->OpenOutputFileW(B(outFile))) {
            std::printf("OpenOutputFile failed\n");
            return 1;
        }

    std::string cert = OutFile("test_cert.pfx");
    if (pdf->CloseAndSignFile(B(cert), B("123456"), B("Test"), B("")))
        std::printf("PDF file \"%s\" successfully created and signed!\n", outFile.c_str());
    else
        std::printf("CloseAndSignFile failed: %ws\n",
                    (const wchar_t*)pdf->GetLastErrorMessage());
    return 0;
}

This file is in the SDK at examples/activex_cpp/signature_ap/signature_ap.cpp. The build fails if this page and that file ever differ.