PAdES visual representation - Rest PKI Core
The visual representation of a PAdES signature is its visible appearance on the PDF: a text, an image or both, drawn inside a rectangle on one of the pages. It is optional: without it, the signature is invisible, but still valid, and PDF readers list it in their signatures panel.
The visual representation has three parts: the text, the image and the position of the rectangle on the page. Only the position is required.
"visualRepresentation": {
"text": { ... },
"image": { ... },
"position": { ... }
}
From this point on we'll describe calls to Rest PKI Core. Make sure you've read the Get Started article to be able to keep up.
Where to set it
The visual representation is part of the PDF signature options, pdfSignatureOptions, as the visualRepresentation field:
| API | Where |
|---|---|
Signature sessions: POST {endpoint}/api/signature-sessions | pdfSignatureOptions.visualRepresentation, which applies to every PDF signed in the session |
| Signature sessions, predefined documents | documents[].pdfSignatureOptions.visualRepresentation, for one document |
Two-step signatures: POST {endpoint}/api/signature | pdfSignatureOptions.visualRepresentation |
PDF stamps: POST {endpoint}/api/pdf/stamp | visualRepresentation, at the top level of the request. It takes the same model described here, but the tags of the text are not replaced: there is no signer, so they stay as written |
When a predefined document of a signature session has its own pdfSignatureOptions, it replaces the session's pdfSignatureOptions entirely: the
two are not merged, so repeat the visualRepresentation in the document. The exception is convertToPdfA, which the document inherits from the session
(see PDF/A conversion).
The legacy Rest PKI APIs that Rest PKI Core still serves (see Moving from Rest PKI)
take the same model in the visualRepresentation field of the request.
Text
The text object draws a text in the rectangle:
| Field | Description |
|---|---|
text | The text, which can have {{tags}} (see below) and line breaks. Required whenever text is sent: a text object without it fails |
includeSigningTime | When true, adds a line with the signing time, formatted with the date and time settings of the organization. Default: false |
fontSize | The maximum font size, in points: the text shrinks, when needed, to fit the rectangle. Default: 12 |
horizontalAlign | Left (default) or Right |
container | The region of the signature rectangle where the text is drawn, as a rectangle relative to the signature rectangle (not to the page). If omitted, the text can use the whole signature rectangle. The text is aligned to the top of the region |
For instance, to leave a margin of 0.2 around the text:
"text": {
"text": "Digitally signed by {{name}}",
"fontSize": 9,
"includeSigningTime": true,
"horizontalAlign": "Left",
"container": { "left": 0.2, "top": 0.2, "right": 0.2, "bottom": 0.2 }
}
Tags
In a signature, the tags in text are replaced with data of the signer's certificate (in a stamp, they stay as written). They are case-sensitive, and an unknown tag stays in the text as written. The most
used:
| Tag | Value |
|---|---|
{{name}} | The signer's full name |
{{national_id}} | The signer's national ID (for ICP-Brasil certificates, the holder's CPF) |
{{email}} | The signer's email address |
{{issuer_cn}} | The common name of the certificate's issuer |
{{br_cpf_formatted}} | The holder's CPF, formatted as 000.000.000-00 (ICP-Brasil certificates) |
{{br_cpf_masked}} | The holder's CPF, masked (ICP-Brasil certificates) |
See the full list of tags, which are the same as those of Rest PKI.
Image
The image object draws an image in the rectangle, behind the text:
| Field | Description |
|---|---|
resource | The image, as url (a link the server downloads the image from; the image is cached for about 5 minutes) or content (the bytes in Base64). One of them is required, and content prevails when both are sent |
opacity | From 0 to 100. Default: 100 |
horizontalAlign | Left, Center (default) or Right |
verticalAlign | Top, Center (default) or Bottom |
The image is scaled to fit the rectangle, keeping its aspect ratio. When the rectangle is wider than the scaled image, horizontalAlign places it;
otherwise, verticalAlign does.
"image": {
"resource": { "url": "https://example.com/seal.png" },
"opacity": 40,
"horizontalAlign": "Right",
"verticalAlign": "Center"
}
Position
The position object says on which page the signature goes and where on it. It has the page, the units of measurement and one of the two ways of
choosing the rectangle: manual or auto.
| Field | Description |
|---|---|
pageNumber | The page: 1 is the first page; negative numbers count from the end (-1 is the last page); 0 appends a new page at the end of the PDF, but only if the PDF has no visible signature yet (otherwise, the last page is used). If omitted, it is 0. A page number beyond the number of pages makes the signature fail |
measurementUnits | Centimeters or PdfPoints (1/72 of an inch). If omitted, the value of measurementUnits in pdfSignatureOptions is used and, without it, Centimeters. It applies to every measure of the position and to the container of the text |
manual | A fixed rectangle on the page: see Manual positioning |
auto | A region of the page where the signatures are placed one after the other: see Automatic positioning |
pageOptimization | Deprecated. It also exists in pdfSignatureOptions, and the one in the position takes precedence. Measures in centimeters are scaled to a reference paper size that Rest PKI Core estimates from the proportions of the page (Letter, Legal or, otherwise, A4), unless pageOptimization says the paper size (paperSize, such as A4 or Letter, or Custom with customPaperSize) and the pageOrientation. So, on pages of non-standard size, such as A3, the sizes scale with the page: to have absolute sizes, use PdfPoints |
If both manual and auto are sent, auto is used. If neither is, the signature fails.
Rectangles
Rectangles, such as the manual rectangle, the auto container and the container of the text, are defined by the parameters left, top, right,
bottom, width and height, which are margins relative to what contains the rectangle (the page, or the signature rectangle). You don't set all of
them: what you set decides how the rectangle behaves.
The rectangle, in red, has its margins relative to what contains it. Don't set left, right and width together: horizontally, two of the three (or only width) are
enough, and the rest takes up the remaining space. Vertically it works the same way, with top, bottom and height in place of left, right and
width. The examples below show the ways of defining the horizontal dimensions. For more on how rectangles work, see
Defining a container, from the PKI SDK.
Fluid
If you set only left and right, the rectangle keeps both margins and its width stretches to fill the remaining space.
Left-anchored
If you set only left and width, the rectangle keeps the left margin and the width. The right margin takes up the remaining space.
Right-anchored
If you set only right and width, the rectangle keeps the right margin and the width. The left margin takes up the remaining space.
Centered
If you set only width, the rectangle is centered horizontally with the given width.
Manual positioning
In manual, the rectangle of the signature is fixed, relative to the page. For instance, a rectangle of 7 by 3 cm, with a margin of 2.5 cm from the left
and bottom edges:
"position": {
"pageNumber": 1,
"measurementUnits": "Centimeters",
"manual": { "left": 2.5, "bottom": 2.5, "width": 7, "height": 3 }
}
Automatic positioning
In auto, you define a container, a region of the page, and the size of each signature, and Rest PKI Core places the signatures one after the other
inside the container. It suits documents with several signers, since you don't know the position of each one.
| Field | Description |
|---|---|
container | The region of the page that receives the signatures, as a rectangle. Required |
signatureRectangleSize | The width and height of the rectangle of each signature. Required |
rowSpacing | The space between rows. Default: 0 |
horizontalDirection | LeftToRight (default) or RightToLeft: the direction in which a row fills |
verticalDirection | TopDown (default) or BottomUp: the direction in which the rows stack |
To choose the position of a signature, Rest PKI Core looks at the last visible signature already on the page, regardless of who made it or with which
tool. If the row still has room for another rectangle of the same size, the new signature goes in that row. Otherwise, it goes in a new row, below
(TopDown) or above (BottomUp) the previous one, separated from it by rowSpacing. A row fits as many signatures as the whole number of times the
width of the signature fits in the width of the container. The rows are justified: the columns of a row are spread evenly across the width of the
container, the first against one edge and the last against the other, so there are gaps between the signatures (about 0.73 cm with the
Footnote preset, on A4 portrait).
When the container is full, the signature is still made, but without a visible representation, and no error is returned. Size the container for the number of signers you expect. Rest PKI Core doesn't look for free spaces in the container, nor does it check the other content of the page.
Presets
The presets return a position object with the usual geometry, ready to use as it is, in the position field of the visual representation. They are
GET routes that need no authentication:
| Route | Parameters | Position |
|---|---|---|
GET {endpoint}/Api/PadesVisualPositioningPresets/Footnote | pageNumber (default -1, the last page); rows (default 1) | A footnote: the signatures go at the bottom of the page, in a container with margins of 1 cm on the left, right and bottom and a height for the given number of rows, filled from the top, from left to right |
GET {endpoint}/Api/PadesVisualPositioningPresets/FootnoteBottomUp | pageNumber (default -1, the last page) | The container is the whole page, minus a margin of 1 cm on each side, and the rows stack from the bottom up |
GET {endpoint}/Api/PadesVisualPositioningPresets/NewPage | None | The signatures go on a new page, with a margin of 1 cm, as in pageNumber 0 |
The three presets use signature rectangles of 4.2 x 1.8 cm, with a spacing of 0.3 cm between rows. On an A4 portrait page, that makes 4 signatures per row.
For example, GET {endpoint}/Api/PadesVisualPositioningPresets/Footnote?pageNumber=-1&rows=2 returns a position for two rows of signatures at the
bottom of the last page, which fits up to 8 signatures on A4 portrait.
Examples
Footnote with a single row
The signatures go at the bottom of the last page, in a single row: on A4 portrait, up to 4 signatures. This is the Footnote preset with one row, with a
text and an image. In a signature session:
POST {endpoint}/api/signature-sessions
{
...
"pdfSignatureOptions": {
"visualRepresentation": {
"text": {
"text": "Digitally signed by {{name}}\nCPF: {{br_cpf_formatted}}",
"fontSize": 9,
"includeSigningTime": true,
"horizontalAlign": "Left",
"container": { "left": 0.2, "top": 0.2, "right": 0.2, "bottom": 0.2 }
},
"image": {
"resource": { "url": "https://example.com/seal.png" },
"opacity": 40,
"horizontalAlign": "Right",
"verticalAlign": "Center"
},
"position": {
"pageNumber": -1,
"measurementUnits": "Centimeters",
"auto": {
"container": { "left": 1.0, "right": 1.0, "bottom": 1.0, "height": 1.8 },
"signatureRectangleSize": { "width": 4.2, "height": 1.8 },
"rowSpacing": 0.3,
"horizontalDirection": "LeftToRight",
"verticalDirection": "TopDown"
}
}
}
}
}
A fifth signer would not have a visible representation: see the warning above.
The PKI Suite Samples use this kind of visual representation, with automatic positioning on the last page and a larger signature rectangle:
Two rows, for up to 8 signers
For two rows, the height of the container is the height of two rows plus the spacing between them: 2 x 1.8 + 0.3 = 3.9 cm. The rest is the same as in the
previous example, so only the position is shown:
"position": {
"pageNumber": -1,
"measurementUnits": "Centimeters",
"auto": {
"container": { "left": 1.0, "right": 1.0, "bottom": 1.0, "height": 3.9 },
"signatureRectangleSize": { "width": 4.2, "height": 1.8 },
"rowSpacing": 0.3,
"horizontalDirection": "LeftToRight",
"verticalDirection": "TopDown"
}
}
A fixed rectangle, in a two-step signature
A signature at a fixed position of the first page, with only the text:
POST {endpoint}/api/signature
{
"file": {
"content": "JVBERi0x...",
"name": "document.pdf"
},
"certificate": {
"content": "MIIG..."
},
"signatureType": "Pdf",
"pdfSignatureOptions": {
"visualRepresentation": {
"text": {
"text": "Signed by {{name}}",
"includeSigningTime": true
},
"position": {
"pageNumber": 1,
"measurementUnits": "Centimeters",
"manual": { "left": 2.5, "bottom": 2.5, "width": 7, "height": 3 }
}
}
}
}
On .NET
The .NET client has no dedicated helpers for the visual representation: you build it with the models of the API, in the Lacuna.RestPki.Api.PadesSignature
namespace, and set it in the VisualRepresentation property of PdfSignatureOptions (or of StampPdfOptions, for a stamp). The classes are PadesVisualRepresentationModel, with
PadesVisualTextModel, PadesVisualImageModel (whose Resource is a ResourceContentOrReference) and PadesVisualPositioningModel, which in turn has
a PadesVisualAutoPositioningModel or a PadesVisualRectangleModel for manual positioning. Their properties have the names of the JSON fields described above, in PascalCase. See how the .NET sample builds one.
See also
- Two-step signatures
- Signature sessions
- PDF stamps
- Tags of the visual representation
- PDF validation marks, which are not part of the visual representation of a signature