pdfa/markup_annotations_pdfa3b
Create various types of markup annotations in PDF/A-3b mode.
Download Java Code Switch to PHP Code Show Output
/*
* Markup annotations:
* Create various types of markup annotations in PDF/A-3b mode.
* This topic is almost identical to interactive/markup_annotations except
* that it creates PDF/A-3b output.
*
* Some annotations are placed by explicitly specifying their rectangle
* coordinates.
*
* The remaining annotations are placed over text fragments in a Textflow.
* These locations are referenced by named matchboxes in the Textflow.
* The options "matchbox" and "matchbox end" define the matchboxes in
* the Textflow. The names are later used for creating the annotations;
* explicit coordinates are not required in this case.
*
* For the Highlight annotation a corresponding Popup annotation is created.
*
* The following types of Markup annotations are demonstrated:
* Caret, Circle, FileAttachment, FreeText, Highlight, Line, Square, Squiggly,
* StrikeOut, Text (=sticky note), Underline
*
* The following types of Markup annotations are not demonstrated here:
* Ink, Polygon, PolyLine
*
* Required software: PDFlib/PDFlib+PDI/PPS 10
* Required data: font
*/
package com.pdflib.cookbook.pdflib.pdfa;
import com.pdflib.pdflib;
import com.pdflib.PDFlibException;
public class markup_annotations_pdfa3b
{
public static void main (String argv[])
{
/* This is where the data files are. Adjust as necessary. */
String searchpath = "../input";
String outfile = "markup_annotations_pdfa3b.pdf";
String title = "Markup annotations in PDF/A-3b";
pdflib p = null;
int exitcode = 0;
try {
double llx, lly, urx, ury;
int asset;
int tf = -1;
p = new pdflib();
p.set_option("searchpath={" + searchpath + "}");
/* This means we must check return values of load_font() etc. */
p.set_option("errorpolicy=return");
if (p.begin_document(outfile, "pdfa=PDF/A-3b destination={type=fitwindow}") == -1)
throw new Exception("Error: " + p.get_errmsg());
p.set_info("Creator", "PDFlib Cookbook");
p.set_info("Title", title);
/* Create page */
p.begin_page_ext(0, 0, "width=a4.width height=a4.height");
// For simplicity we name the matchboxes according to the
// corresponding annotation type that they will hold.
String text =
"Lorem " +
"<matchbox={name=caret boxheight={ascender descender}}>caret<matchbox=end> " +
"ipsum dolor sit amet, consectetur adi­pi­sicing elit, " +
"sed do eius­mod" +
"<matchbox={name=circle boxheight={ascender descender}}> circle <matchbox=end>" +
"tempor incidi­dunt ut labore et dolore magna ali­qua. Ut " +
"<matchbox={name=highlight boxheight={ascender descender}}>highlight<matchbox=end> " +
"enim ad minim ve­niam, quis nostrud " +
"<matchbox={name=line}>line<matchbox=end> " +
"exer­citation ull­amco la­bo­ris nisi ut " +
"<matchbox={name=square boxheight={ascender descender}}>square<matchbox=end> " +
"ali­quip ex ea commodo con­sequat. Duis aute irure dolor in " +
"<matchbox={name=squiggly boxheight={ascender descender}}>squiggly<matchbox=end> " +
"repre­henderit in voluptate velit esse cillum dolore eu " +
"<matchbox={name=strikeout}>strikeout<matchbox=end> " +
"fugiat nulla pari­atur. Excep­teur sint occae­cat " +
"cupi­datat non proident, sunt in culpa qui officia dese­runt " +
"<matchbox={name=underline boxheight={ascender descender}}>underline<matchbox=end> " +
"mollit anim id est laborum. ";
tf = p.create_textflow(text,
"fontname=NotoSerif-Regular fontsize=20 leading=140% charref");
if (tf == -1)
throw new Exception("Error: " + p.get_errmsg());
// Place the Textflow on the page
String result = p.fit_textflow(tf, 50, 50, 550, 550, "fitmethod=auto");
if (!result.equals("_stop"))
{
/* Check for errors */
}
/*
* p.info_matchbox() returns box coordinates in user coordinates
* which we use in calls to create_annotation(). If the user
* coordinate system has been transformed we need this method to
* accept user coordinates. Instead of supplying "usercoordinate=true"
* to individual calls we set it here globally.
*/
p.set_option("usercoordinates=true");
// Create some annotation types with explicit rectangle coordinates
int font = p.load_font("NotoSerif-Bold", "unicode", "");
p.create_annotation(300, 750, 500, 800, "Stamp", "contents={Stamp annotation} font=" + font);
p.create_annotation(50, 750, 75, 800, "Text",
"contents={My little note...} open=false iconname=comment annotcolor=red");
/* File attachment annotation */
asset = p.load_asset("Attachment", "af1.txt", "description={Simple text file}");
if (asset == -1)
throw new Exception("Error: " + p.get_errmsg());
p.create_annotation(50, 700, 75, 725, "FileAttachment",
"attachment=" + asset + " contents={My file attachment} iconname=pushpin annotcolor=blue");
/* FreeText annotation with a callout line pointing to the
* top left corner of the Textflow box.
*/
llx = 200;
lly = 600;
urx = 350;
ury = 650;
font = p.load_font("NotoSerif-Regular", "unicode", "");
p.create_annotation(llx, lly, urx, ury, "FreeText",
"contents={FreeText with callout line} calloutline={" +
"50 550 " + // start point (what it points to)
(llx+50)/2 + " " + (lly + ury)/2 + " " + // optional knee point
llx + " " + (lly + ury)/2 + "} " + // end point (on the annotation border)
"endingstyles={closedarrow none} fontsize=12 font=" + font + " annotcolor=yellow fillcolor=red");
/* Create various annotation types in the corresponding matchboxes
* in the Textflow. Since we use matchboxes as target rectangles
* we can supply the annotation coordinates as 0, 0, 0, 0.
*/
p.create_annotation(0, 0, 0, 0, "Caret", "usematchbox=caret annotcolor=blue");
p.create_annotation(0, 0, 0, 0, "Circle", "usematchbox=circle linewidth=2 annotcolor=purple interiorcolor=purple opacity=0.25");
// Attach Popup to the Highlight annotation via name
p.create_annotation(0, 0, 0, 0, "Highlight", "name=my_highlight title={My highlight} contents={My comment in the Popup...} usematchbox=highlight linewidth=3 annotcolor=red");
/* Create a Popup annotation for the Highlight annotation.
* Fetch corner coordinates of the parent Highlight annotation so
* that we can place the corresponding Popup close to it.
*/
llx = p.info_matchbox("highlight", 1, "x1") + 50;
lly = p.info_matchbox("highlight", 1, "y1") + 150;
p.create_annotation(llx, lly, llx+150, lly+100, "Popup", "parentname=my_highlight open");
// Fetch corner coordinates so that we can draw a diagonal line
llx = p.info_matchbox("line", 1, "x1");
lly = p.info_matchbox("line", 1, "y1");
urx = p.info_matchbox("line", 1, "x3");
ury = p.info_matchbox("line", 1, "y3");
p.create_annotation(0, 0, 0, 0, "Line", "usematchbox=line line={" + llx + " " + lly + " " + urx + " " + ury + "} linewidth=3 annotcolor=green");
p.create_annotation(0, 0, 0, 0, "Square", "usematchbox=square cloudy=1 linewidth=2 annotcolor=magenta");
p.create_annotation(0, 0, 0, 0, "Squiggly", "usematchbox=squiggly annotcolor=blue");
p.create_annotation(0, 0, 0, 0, "Strikeout", "usematchbox=strikeout annotcolor=red");
p.create_annotation(0, 0, 0, 0, "Underline", "usematchbox=underline annotcolor=purple");
p.end_page_ext("");
p.end_document("");
} catch (PDFlibException e){
System.err.println("PDFlib exception occurred:");
System.err.println("[" + e.get_errnum() + "] " + e.get_apiname() +
": " + e.get_errmsg());
exitcode = 1;
} catch (Exception e) {
System.err.println(e.toString());
exitcode = 1;
} finally {
if (p != null) {
p.delete();
}
System.exit(exitcode);
}
}
}