PDFlib で、多角形を回り込むテキストを作成するサンプルプログラムです。テキストフローのフィットボックスに対応して配置される三角形の周りをテキストが回り込むようにfit_textflow 関数の wrap オプションと polygons サブオプションを使います。これにより、ページ上に配置される二つの六角形をテキストが回り込みます。
/*
* Wrap text around polygons:
* Use arbitrary polygons as wrapping shapes for text to wrap around
*
* Use fit_textflow() with the "wrap" option and the "polygons" suboption to
* wrap text around a triangle positioned relative to the fitbox of the
* Textflow. Then wrap text around two hexagons positioned with absolute
* coordinates on the page.
*
* 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 wrap_text_around_polygons
{
public static void main (String argv[])
{
pdflib p = null;
String searchpath = "../input";
String outfile = "wrap_text_around_polygons.pdf";
String title = "Wrap Text around Polygons";
int i, tf = -1;
String result, heading;
final double llx = 70, lly = 50, urx = 450, ury = 820;
int exitcode = 0;
/* Repeat the dummy text to produce more contents */
final int count = 6;
final String optlist1 =
"fontname=NotoSerif-Regular fontsize=10.5 " +
"fillcolor={gray 0} alignment=justify";
final String optlist2 =
"fontname=NotoSerif-Bold fontsize=11 " +
"fillcolor={rgb 0 0 1} charref";
/* Text which is repeatedly placed on the page. Soft hyphens are marked
* with the character reference "­" (character references are enabled
* by the charref option).
*/
final String text =
"Our paper planes are the ideal way of passing the time. We offer " +
"revolutionary new develop­ments of the traditional common paper " +
"planes. If your lesson, conference, or lecture turn out to be " +
"deadly boring, you can have a wonderful time with our planes. " +
"All our models are fol­ded from one paper sheet. They are " +
"exclu­sively folded with­out using any adhesive. Several " +
"models are equipped with a folded landing gear enabling a safe " +
"landing on the intended loca­tion provided that you have aimed " +
"well. Other models are able to fly loops or cover long distances. " +
"Let them start from a vista point in the mountains and see where " +
"they touch the ground. ";
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");
p.set_option("charref=true");
if (p.begin_document(outfile, "") == -1)
throw new Exception("Error: " + p.get_errmsg());
p.set_info("Creator", "PDFlib Cookbook");
p.set_info("Title", title);
/* ---------------------------
* Wrap text around a triangle
* ---------------------------
*/
/* Create a heading */
heading = "Page 1: fit_textflow() with option\n" +
"wrap={polygons={{50% 80% 20% 30% 80% 30% 50% 80%}}}\n\n";
tf = p.add_textflow(tf, heading, optlist2);
if (tf == -1)
throw new Exception("Error: " + p.get_errmsg());
/* 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.
*/
do {
p.begin_page_ext(0, 0, "width=a4.width height=a4.height");
/* Place the text. Use the "wrap" option with the "polygons"
* suboption to define a triangle. In this case, each corner of the
* triangle is specified by a pair of coordinates defined as
* percentage of the fitbox width or height, respectively.
*/
result = p.fit_textflow(tf, llx, lly, urx, ury,
"verticalalign=justify linespreadlimit=120% " +
"wrap={ polygons={ {50% 80% 20% 30% 80% 30% 50% 80%} } }");
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);
/* -----------------------------
* Wrap text around two hexagons
* -----------------------------
*/
tf = -1;
/* Create a heading */
heading = "Page 2: fit_textflow() with option " +
"wrap={ polygons={\n{150 250 200 350 300 350 350 250 " +
"300 150 200 150 150 250}\n{130 550 200 650 300 650 " +
"370 550 300 450 200 450 130 550}}}\n\n";
tf = p.add_textflow(tf, heading, optlist2);
if (tf == -1)
throw new Exception("Error: " + p.get_errmsg());
/* 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.
*/
do {
p.begin_page_ext(0, 0, "width=a4.width height=a4.height");
/* Place the text. Use the "wrap" option with the "polygons"
* suboption to define two hexagons. In this case, each corner of
* the hexagons is specified by a pair of absolute coordinates on
* the page.
*/
result = p.fit_textflow(tf, llx, lly, urx, ury,
"verticalalign=justify linespreadlimit=120% wrap={ polygons={" +
"{150 250 200 350 300 350 350 250 300 150 200 150 150 250} " +
"{130 550 200 650 300 650 370 550 300 450 200 450 130 550}} }");
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);
}
}
}