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 PHP Code Switch to Java Code Show Output
<?php
/*
* 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
*/
function create_shading($p, $tf) {
/*
* Query formatting results of the Textflow (coordinates of the placed
* text)
*/
$llx = $p->info_textflow($tf, "x1");
$lly = $p->info_textflow($tf, "y1");
$urx = $p->info_textflow($tf, "x3");
$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).
*/
$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 * sqrt(pow($ury - $lly, 2) + pow($urx - $llx, 2))));
return $p->shading_pattern($sh, "");
}
/* This is where the data files are. Adjust as necessary. */
$searchpath = dirname(__FILE__,3)."/input";
$title = "Starter Textflow";
$tf = 0;
$llx1 = 50;
$lly1 = 50;
$urx1 = 250;
$ury1 = 800;
$llx2 = 300;
$lly2 = 50;
$urx2 = 500;
$ury2 = 800;
$exitcode = 0;
/* Repeat the dummy text to produce more contents */
$count = 50;
$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).
*/
$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. ";
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("", "") == 0)
throw new Exception("Error: " . $p->get_errmsg());
$p->set_info("Creator", "PDFlib Cookbook");
$p->set_info("Title", $title);
$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 ++) {
$num = $i . " ";
$tf = $p->add_textflow($tf, $num, $optlist2);
if ($tf == 0)
throw new Exception("Error: " . $p->get_errmsg());
$tf = $p->add_textflow($tf, $text, $optlist1);
if ($tf == 0)
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 */
$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 */
$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 != "_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 == "_boxfull" || $result == "_nextpage" );
/* Check for errors */
if ($result != "_stop") {
/*
* "_boxempty" happens if the box is very small and doesn't hold
* any text at all.
*/
if ($result == "_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("");
$buf = $p->get_buffer();
$len = strlen($buf);
header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=textflow_with_shading.pdf");
print $buf;
}
catch (PDFlibException $e) {
echo ("PDFlib exception occurred:\n" . "[" . $e->get_errnum() . "] " .
$e->get_apiname() . ": " . $e->get_errmsg() . "\n");
exit(1);
}
catch (Throwable $e) {
echo ("PHP exception occurred: " . $e->getMessage() . "\n");
exit(1);
}
$p = 0;
?>