Skip to content

sync main with develop for upcoming RC 18.0.5PlusP1n #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 58 additions & 16 deletions Images/RenderPage/RenderPage.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//
// Copyright (c) 2007-2024, Datalogics, Inc. All rights reserved.
// Copyright (c) 2007-2025, Datalogics, Inc. All rights reserved.
//
// The RenderPage sample program shows how to render a PDF document page to memory.
//

#include "RenderPage.h"
Expand Down Expand Up @@ -62,11 +64,43 @@ void ASDoubleToFixedRect(ASFixedRect &out, ASDoubleRect &in) {
out.bottom = FloatToASFixed(in.bottom);
}

// If a Page Background color is desired, set it here
void RenderPage::SetBackgroundColor() {
bool hasAlpha = (csAtom == sDeviceRGBA_K || csAtom == sDeviceCMYKA_K);

int stride = attrs.width * nComps;
while (stride % 4 != 0)
{
stride++;
}

// Determine zero padding length
int padding = stride - (attrs.width * nComps);

char* bufferPtr = buffer;
// Walk the buffer and fill in the chosen background color and possibly the alpha value
for (int heightIndex = 0; heightIndex < attrs.height; heightIndex++) {
for (int rowIndex = 0; (rowIndex + pageBackgroundColor.color.numChannels) < stride; rowIndex += pageBackgroundColor.color.numChannels) {
memcpy(bufferPtr, &pageBackgroundColor.color.value[0], pageBackgroundColor.color.numChannels);
bufferPtr += pageBackgroundColor.color.numChannels;
if (hasAlpha) {
memcpy(bufferPtr++, &pageBackgroundColor.alphaValue, 1);
rowIndex++;
}
}
// If zero padding is needed fill it here
if (padding > 0) {
memset(bufferPtr, 0x00, padding);
bufferPtr += padding;
}
}
}

// This both constructs the RenderPage object, and creates the page rendering.
// The rendered page can be accessed as a bitmap via the methods GetImageBuffer() and GetImageBufferSize(), or as a PDEImage,
// via the method GetPDEImage(). The PDEImage creation will be deferred until it is requested.
RenderPage::RenderPage(PDPage &pdPage, const char *colorSpace, const char *filterName,
ASInt32 inBPC, double inResolution, float userUnit) {
ASInt32 inBPC, double inResolution, float userUnit, bool setBackgroundColor, BackgroundColor pageColor) {
// Set up the static colorspace atoms
sDeviceRGB_K = ASAtomFromString("DeviceRGB");
sDeviceRGBA_K = ASAtomFromString("DeviceRGBA");
Expand Down Expand Up @@ -162,7 +196,7 @@ RenderPage::RenderPage(PDPage &pdPage, const char *colorSpace, const char *filte
attrs.width = (ASInt32)floor(((cropRect.right * resolution) * (userUnit / 72.0)) + 0.5);
attrs.height = (ASInt32)floor(((cropRect.top * resolution) * (userUnit / 72.0)) + 0.5);

// Set up the destinantion rectangle.
// Set up the destination rectangle.
// This is a description of the image in pixels, so it will always
// have it's origin at 0,0.
ASRealRect destRect;
Expand All @@ -184,24 +218,25 @@ RenderPage::RenderPage(PDPage &pdPage, const char *colorSpace, const char *filte
PDPageDrawMParamsRec drawParams;

// Many of the values in the params record will not be used for this simple rendering.
// so we set them all to zeros initally
// so we set them all to zeros initially
memset(&drawParams, 0, sizeof(PDPageDrawMParamsRec));
drawParams.size = sizeof(PDPageDrawMParamsRec);
drawParams.csAtom = csAtom;
drawParams.bpc = bpc;

// For this example we will smooth (anti-alias) all of the marks. For a given application,
// this may or may not be desireable. See the enumeration PDPageDrawSmoothFlags for the full set of options.
// this may or may not be desirable. See the enumeration PDPageDrawSmoothFlags for the full set of options.
drawParams.smoothFlags = kPDPageDrawSmoothText | kPDPageDrawSmoothLineArt | kPDPageDrawSmoothImage;

// The DoLazyErase flag is usually, if not always turned on, UseAnnotFaces will cause
// annotations in the page to be displayed, and kPDPageDsiplayOverprintPreview will display the
// page showing overprinting. The precise meaning of these flags, as well as others that may be
// used here, can be seen in the defintion of PDPageDrawFlags
drawParams.flags = kPDPageDoLazyErase | kPDPageUseAnnotFaces | kPDPageDisplayOverPrintPreview | kPDPageEmitPageGroup;
// Only set the LazyErase flag if user hasn't specified a Background Color
if (!setBackgroundColor){
drawParams.flags = kPDPageDoLazyErase;
}

drawParams.flags |= kPDPageUseAnnotFaces | kPDPageDisplayOverPrintPreview | kPDPageEmitPageGroup;

// This is a bit clumsy, because features were added over time. The matrices and rectangles in
// this interface use ASReal as thier base, rather than ASDouble. But there is not a complete
// this interface use ASReal as their base, rather than ASDouble. But there is not a complete
// set of concatenation and transformation methods for ASReal. So we generally generate the
// matrix and rectangle values using ASDouble, and convert to ASReal.
ASDoubleRect doubleUpdateRect;
Expand All @@ -221,7 +256,7 @@ RenderPage::RenderPage(PDPage &pdPage, const char *colorSpace, const char *filte
// to be rendered.

// Additional values in this record control such features as drawing separations,
// specifiying a desired output profile, selecting optional content, and providing for
// specifying a desired output profile, selecting optional content, and providing for
// a progress reporting callback.

// Allocate the buffer for storing the rendered page content
Expand All @@ -236,12 +271,19 @@ RenderPage::RenderPage(PDPage &pdPage, const char *colorSpace, const char *filte
// One frequent failure point in rendering images is being unable to allocate sufficient contigious space
// for the bitmap buffer. Here, that will be indicated by a zero value for drawParams.buffer after the
// call to malloc. If the buffer size is larger than the internal limit of malloc, it may also raise an
// interupt! Catch these conditions here, and raise an out of memory error to the caller.
// interrupt! Catch these conditions here, and raise an out of memory error to the caller.
try {
buffer = (char *)ASmalloc(bufferSize);
buffer = (char*)ASmalloc(bufferSize);

if (setBackgroundColor) {
pageBackgroundColor = pageColor;
SetBackgroundColor();
}

if (!buffer)
ASRaise(genErrNoMemory);
} catch (...) {
}
catch (...) {
ASRaise(genErrNoMemory);
}

Expand Down Expand Up @@ -417,7 +459,7 @@ PDEFilterArray RenderPage::SetDCTFilterParams(CosDoc cosDoc) {
CosObj dictParams = CosNewDict(cosDoc, false, 4);

// Populate the dictionary with required entries to do JPEG compression
// (only Columns, Rows, and the number of color dimensions needed for JPEG)
// (only Columns, Rows, and the number of color dimensions needed for straight JPEG)
CosDictPut(dictParams, ASAtomFromString("Columns"), CosNewInteger(cosDoc, false, attrs.width));
CosDictPut(dictParams, ASAtomFromString("Rows"), CosNewInteger(cosDoc, false, attrs.height));
CosDictPut(dictParams, ASAtomFromString("Colors"), CosNewInteger(cosDoc, false, nComps));
Expand Down
17 changes: 15 additions & 2 deletions Images/RenderPage/RenderPage.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2017-2024, Datalogics, Inc. All rights reserved.
// Copyright (c) 2017-2025, Datalogics, Inc. All rights reserved.
//
// Sample: RenderPage
//
Expand All @@ -20,6 +20,16 @@
#include "PDFLCalls.h"
#include "DLExtrasCalls.h"

struct Color {
ASUns8* value;
int numChannels;
};

struct BackgroundColor {
Color color;
ASUns8 alphaValue;
};

class RenderPage {
private:
PDPage pdPage;
Expand All @@ -33,6 +43,7 @@ class RenderPage {
char *buffer;
char *colorSpace;
char *filterName;
BackgroundColor pageBackgroundColor;

ASFixedRect imageSize; // This will carry the image size in PDF units.

Expand All @@ -49,9 +60,11 @@ class RenderPage {
static ASAtom sDeviceGray_K;

public:
RenderPage(PDPage &pdPage, const char *colorSpace, const char *filterName, ASInt32 bpc, double resolution, float userUnit);
RenderPage(PDPage &pdPage, const char *colorSpace, const char *filterName, ASInt32 bpc, double resolution, float userUnit, bool setBackgroundColor, BackgroundColor backgroundColor);
~RenderPage();

void SetBackgroundColor();

char *GetImageBuffer();
ASSize_t GetImageBufferSize();
PDEImage GetPDEImage(PDDoc outDoc);
Expand Down
29 changes: 22 additions & 7 deletions Images/RenderPage/mainproc.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2007-2024, Datalogics, Inc. All rights reserved.
// Copyright (c) 2007-2025, Datalogics, Inc. All rights reserved.
//
// Sample: RenderPage - Demonstrates the process of rasterizing the cropped area of a PDF page
// and placing the resulting raster as an image into a different PDF document.
Expand All @@ -24,10 +24,18 @@
#define FILTER "FlateDecode"
#define BPC 8 // This must be 8 for DeviceRGB and DeviceCMYK, 1, 8, or 24 for DeviceGray
#define COLORSPACE "DeviceRGB" // Typically this, DeviceGray, or DeviceCMYK
// DeviceRGBA is a special colorspace known to PDFL Rendering that can be used to produce a RGBA Bitmap (RGB + Alpha or 32-bit),
// which is output in this sample as a RGB Image with a Soft Mask set on the page of a PDF
// DeviceCMYKA is a special colorspace known to PDFL Rendering that can be used to produce a CMYKA Bitmap (CMYK + Alpha or 40-bit)
// which is output in this sample as a CMYK Image with a Soft Mask set on the page of a PDF
/* DeviceRGBA is a special colorspace known to PDFL Rendering that can be used to produce a RGBA Bitmap(RGB + Alpha or 32 - bit),
which is output in this sample as a RGB Image with a Soft Mask set on the page of a PDF
DeviceCMYKA is a special colorspace known to PDFL Rendering that can be used to produce a CMYKA Bitmap (CMYK + Alpha or 40-bit)
which is output in this sample as a CMYK Image with a Soft Mask set on the page of a PDF*/

// When enabled, the BACKGROUND_COLOR and ALPHA_VALUE are utilized for the Background of the Rendered Page
#define SET_BACK_COLOR false
// Background color, number of elements should correspond to COLORSPACE, defaults to Blue in terms of DeviceRGB
ASUns8 BACKGROUND_COLOR[] = { 0x00, 0x00, 0xFF};

// Only applicable if COLORSPACE is DeviceRGBA or DeviceCMYKA, defaults to 50% translucent
#define ALPHA_VALUE 0x80

int main(int argc, char **argv) {
ASErrorCode errCode = 0;
Expand All @@ -51,16 +59,23 @@ int main(int argc, char **argv) {
<< FILTER << ", and BPC " << BPC << std::endl;

DURING

// Open the input document and acquire the first page
APDFLDoc inDoc(csInputFileName.c_str(), true);
PDPage pdPage = inDoc.getPage(0);

// Get the UserUnit of the Page
float userUnit = PDPageGetUserUnitSize(pdPage);

Color backgroundColor;
backgroundColor.value = &BACKGROUND_COLOR[0];
backgroundColor.numChannels = sizeof(BACKGROUND_COLOR);

BackgroundColor pageColor;
pageColor.alphaValue = ALPHA_VALUE;
pageColor.color = backgroundColor;

// Construction of the drawPage object does all the work to rasterize the page
RenderPage drawPage(pdPage, COLORSPACE, FILTER, BPC, RESOLUTION, userUnit);
RenderPage drawPage(pdPage, COLORSPACE, FILTER, BPC, RESOLUTION, userUnit, SET_BACK_COLOR, pageColor);

// Release the first page.
PDPageRelease(pdPage);
Expand Down
139 changes: 139 additions & 0 deletions Security/AddDigitalSignature/AddDigitalSignature.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
//
// Copyright (c) 2025, Datalogics, Inc. All rights reserved.
//
// This sample adds a digital signature with a logo to a PDF document.
//
// Command-line: <input-file> <output-file> <logo file> (All optional)
//

#include <iostream>
#include <string>
#include "InitializeLibrary.h"
#include "APDFLDoc.h"
#include "PERCalls.h"

// Header that includes Digital Signature methods
#include "DLExtrasCalls.h"

#define INPUT_LOC "../../../../Resources/Sample_Input/"
#define DEF_INPUT "SixPages.pdf"
#define DEF_OUTPUT "AddDigitalSignature-out.pdf"
#define DEF_LOGO_FILE "ducky_alpha.tif"

// DEF_CERT_FILE points to the signer certificate which may be binary(.der file format)
// or base-64 encoded(.pem file format).
#define DEF_CERT_FILE "Credentials/DER/RSA_certificate.der"

// DEF_KEY_FILE points to the private key corresponding to the signer certificate defined above.
// A key can be binary (.der file format) or base-64 encoded (.pem file format).
#define DEF_KEY_FILE "Credentials/DER/RSA_privKey.der"

int main(int argc, char **argv) {
APDFLib lib;

ASErrorCode errCode = 0;
if (lib.isValid() == false) {
errCode = lib.getInitError();
std::cout << "Initialization failed with code " << errCode << std::endl;
return errCode;
}

std::string const csInputFileName(argc > 1 ? argv[1] : INPUT_LOC DEF_INPUT);
std::string const csOutputFileName(argc > 2 ? argv[2] : DEF_OUTPUT);
std::string const csLogoFileName(argc > 3 ? argv[2] : INPUT_LOC DEF_LOGO_FILE);
std::cout << "Will apply a digital signature to " << csInputFileName.c_str() << " with a logo "
<< csLogoFileName.c_str() << " and save as " << csOutputFileName.c_str() << std::endl;

DURING

// Open the input document.
APDFLDoc APDoc(csInputFileName.c_str(), true);
PDDoc inDoc = APDoc.getPDDoc();

// Setup Sign params
PDSignDocSignParams const signParams = PDSignDocSignInitParams();

PDSignDocSetFieldID(signParams, CreateFieldWithQualifiedName);

// Set the size and location of the signature box (optional)
// If not set, invisible signature will be placed on first page
ASFixedRect annotLocation;
annotLocation.left = ASFloatToFixed(1.0 * 72);
annotLocation.right = ASFloatToFixed(4.0 * 72);
annotLocation.top = ASFloatToFixed(6.0 * 72);
annotLocation.bottom = ASFloatToFixed(8.0 * 72);
PDSignDocSetSignatureBoxPageNumber(signParams, 0);
PDSignDocSetSignatureBoxRectangle(signParams, &annotLocation);

ASText fieldName = ASTextFromEncoded("Signature_es_:signatureblock", PDGetHostEncoding());
PDSignDocSetFieldName(signParams, fieldName);

// Set credential related attributes
PDSignDocSetDigestCategory(signParams, sha256);
PDSignDocSetCredentialDataFormat(signParams, NonPFX);

ASPathName certPath = APDFLDoc::makePath(INPUT_LOC DEF_CERT_FILE);
ASPathName keyPath = APDFLDoc::makePath(INPUT_LOC DEF_KEY_FILE);

ASFile asCertFileDER{nullptr};
ASErrorCode err = ASFileSysOpenFile64(nullptr, certPath, (ASFILE_READ | ASFILE_SERIAL), &asCertFileDER);

ASFile asKeyFileDER{nullptr};
err = ASFileSysOpenFile64(nullptr, keyPath, (ASFILE_READ | ASFILE_SERIAL), &asKeyFileDER);

PDSignDocSetNonPfxSignerCert(signParams, asCertFileDER, 0, OnDisk);
PDSignDocSetNonPfxPrivateKey(signParams, asKeyFileDER, 0, OnDisk);

// Setup the signer information
ASText name = ASTextFromEncoded("John Doe", PDGetHostEncoding());
ASText location = ASTextFromEncoded("Chicago, IL", PDGetHostEncoding());
ASText reason = ASTextFromEncoded("Approval", PDGetHostEncoding());
ASText contact = ASTextFromEncoded("Datalogics, Inc.", PDGetHostEncoding());

// Setup the logo image (optional)
ASPathName logoPath = APDFLDoc::makePath(csLogoFileName.c_str());
ASFile asLogoFile{nullptr};
err = ASFileSysOpenFile64(nullptr, logoPath, (ASFILE_READ | ASFILE_SERIAL), &asLogoFile);
PDEImage logo{DLCreatePDEImageFromASFile(asLogoFile)};
ASFixed const opacity{FloatToASFixed(0.50f)};

PDSignDocSetSignerInfo(signParams, logo, opacity, name, location, reason, contact,
DisplayTraits::kDisplayAll);

// Setup Save params
PDSignDocSaveParams const saveParams = PDSignDocSaveInitParams();
ASPathName outPathName = APDFLDoc::makePath(csOutputFileName.c_str());

PDSignDocSetOutputPath(saveParams, outPathName);

// Finally, sign and save the document
PDSignDocWithParams(inDoc, saveParams, signParams);

// Cleanup
ASTextDestroy(fieldName);
ASTextDestroy(name);
ASTextDestroy(location);
ASTextDestroy(reason);
ASTextDestroy(contact);

// Release logo object
PDERelease(reinterpret_cast<PDEObject>(logo));
ASFileSysReleasePath(nullptr, logoPath);

// Release credential objects
ASFileSysReleasePath(nullptr, certPath);
ASFileSysReleasePath(nullptr, keyPath);
ASFileClose(asCertFileDER);
ASFileClose(asKeyFileDER);

ASFileClose(asLogoFile);
PDDocClose(inDoc);
ASFileSysReleasePath(nullptr, outPathName);

HANDLER
errCode = ERRORCODE;
lib.displayError(errCode);
END_HANDLER

return errCode;
};
3 changes: 3 additions & 0 deletions Security/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## AddDigitalSignature
Demonstrates adding a digital signature with a logo to a PDF document.

## AddPassword
Demonstrates protecting a PDF with a password. To open or edit the saved PDF, you must supply the password.

Expand Down
Loading