textflow/textflow_with_shading
Create multi-column output with text and use a shading where the geometry of each shading matches the respective text column.
Download Java Code Switch to PHP Code Show Output
/*
* Textflow with shading:
* Create multi-column text output which may span multiple pages.
* The text columns are colorized with a shading which matches the
* geometry of each column. To emphasize the effect we create a radial
* shading which starts in the middle of the fitbox.
*
* Required software: PDFlib/PDFlib+PDI/PPS 10
* Required data: none
*/
package com.pdflib.cookbook.pdflib.textflow;
import com.pdflib.pdflib;
import com.pdflib.PDFlibException;
public class textflow_with_shading {
static int create_shading(pdflib p, int tf) throws PDFlibException {
/*
* Query formatting results of the Textflow (coordinates of the placed
* text)
*/
double llx = p.info_textflow(tf, "x1");
double lly = p.info_textflow(tf, "y1");
double urx = p.info_textflow(tf, "x3");
double ury = p.info_textflow(tf, "y3");
/*
* Create axial shading from red to blue. The start and end circles have
* their centers in the center of the fitbox. The radius of the start
* circle is zero, the radius of the end circle is chosen so that the
* full fitbox is covered (half of the diagonal).
*/
int sh = p.shading("radial",
(llx + urx) / 2, (lly + ury) / 2,
(llx + urx) / 2, (lly + ury) / 2,
0, 0, 0, 0, // unused color parameters
"startcolor=red endcolor=blue " +
"r0=0 r1=" + 0.5 * Math.sqrt(Math.pow(ury - lly, 2) + Math.pow(urx - llx, 2)));
return p.shading_pattern(sh, "");
}
public static void main(String argv[]) {
/* This is where the data files are. Adjust as necessary. */
String searchpath = "../input";
String outfile = "textflow_with_shading.pdf";
String title = "Starter Textflow";
int i, tf = -1;
String result;
final double llx1 = 50, lly1 = 50, urx1 = 250, ury1 = 800;
final double llx2 = 300, lly2 = 50, urx2 = 500, ury2 = 800;
int exitcode = 0;
/* Repeat the dummy text to produce more contents */
final int count = 50;
final String optlist1 = "fontname=NotoSerif-Regular "
+ "fontsize=10.5 fillcolor={gray 0} alignment=justify "
+ "hyphenchar=U+002D";
/*
* Dummy text for filling the columns. Soft hyphens are marked with the
* character reference "­" (character references are enabled by the
* charref option).
*/
final String text =
"Lorem ipsum dolor sit amet, consectetur adi­pi­sicing elit, "
+ "sed do eius­mod tempor incidi­dunt ut labore et dolore "
+ "magna ali­qua. Ut enim ad minim ve­niam, quis nostrud "
+ "exer­citation ull­amco la­bo­ris nisi ut "
+ "ali­quip ex ea commodo con­sequat. Duis aute irure dolor "
+ "in repre­henderit in voluptate velit esse cillum dolore eu "
+ "fugiat nulla pari­atur. Excep­teur sint occae­cat "
+ "cupi­datat non proident, sunt in culpa qui officia "
+ "dese­runt mollit anim id est laborum. ";
pdflib p = null;
try {
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, "") == -1)
throw new Exception("Error: " + p.get_errmsg());
p.set_info("Creator", "PDFlib Cookbook");
p.set_info("Title", title);
final String optlist2 = "fontname=NotoSerif-Bold fontsize=14 "
+ " charref hyphenchar=U+002D";
/*
* Create some amount of dummy text and feed it to a Textflow object
* with alternating options.
*/
for (i = 1; i <= count; i++) {
String num = i + " ";
tf = p.add_textflow(tf, num, optlist2);
if (tf == -1)
throw new Exception("Error: " + p.get_errmsg());
tf = p.add_textflow(tf, text, optlist1);
if (tf == -1)
throw new Exception("Error: " + p.get_errmsg());
}
/*
* Loop until all of the text is placed; create new pages as long as
* more text needs to be placed. Two columns will be created on all
* pages.
*/
do {
/* Add "showborder" to visualize the fitbox borders */
String optlist = "verticalalign=justify linespreadlimit=120% ";
p.begin_page_ext(0, 0, "width=a4.width height=a4.height");
/* Place the first column in blind mode (for formatting only) */
result = p.fit_textflow(tf, llx1, lly1, urx1, ury1,
optlist + " blind");
/* handle for shading pattern */
int shp = create_shading(p, tf);
/*
* Place the first column in real mode and replace the gray fill
* color with the shading pattern. We must rewind the Textflow
* to undo the result of the "blind" formatting.
*/
result = p.fit_textflow(tf, llx1, lly1, urx1, ury1,
optlist + "rewind=-1 exchangefillcolors={{gray 0} {pattern "
+ shp + "}}");
/* Process the second column if we have more text */
if (!result.equals("_stop")) {
/* Place second column in "blind" mode */
result = p.fit_textflow(tf, llx2, lly2, urx2, ury2,
optlist + " blind");
shp = create_shading(p, tf);
/*
* Place second column in real mode and replace the gray
* fill color with the shading pattern.
*/
result = p.fit_textflow(tf, llx2, lly2, urx2, ury2,
optlist
+ "rewind=-1 exchangefillcolors={{gray 0} {pattern "
+ shp + "}}");
}
p.end_page_ext("");
/*
* "_boxfull" means we must continue because there is more text;
* "_nextpage" is interpreted as "start new column"
*/
}
while (result.equals("_boxfull") || result.equals("_nextpage"));
/* Check for errors */
if (!result.equals("_stop")) {
/*
* "_boxempty" happens if the box is very small and doesn't hold
* any text at all.
*/
if (result.equals("_boxempty"))
throw new Exception("Error: Textflow box too small");
else {
/*
* Any other return value is a user exit caused by the
* "return" option; this requires dedicated code to deal
* with.
*/
throw new Exception(
"User return '" + result + "' found in Textflow");
}
}
p.delete_textflow(tf);
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);
exitcode = 1;
}
finally {
if (p != null) {
p.delete();
}
System.exit(exitcode);
}
}
}