complex_scripts/starter_shaping
Demonstrate text shaping for Arabic, Hebrew, Hindi and Sanskrit scripts. Right-to-left text is reordered according to the Bidi algorithm.
Download Java Code Switch to PHP Code Show Output
/*
* Starter sample for text shaping features
* Demonstrate text shaping for Arabic, Hebrew, and Devanagari scripts
* Right-to-left text is reordered according to the Bidi algorithm.
*
* Required software: PDFlib/PDFlib+PDI/PPS 10
* Required data: suitable fonts for the scripts
*/
package com.pdflib.cookbook.pdflib.complex_scripts;
import com.pdflib.pdflib;
import com.pdflib.PDFlibException;
class starter_shaping {
public static void main(String argv[]) {
/* This is where the data files are. Adjust as necessary. */
final String searchpath = "../input";
final String outfile = "starter_shaping.pdf";
String optlist;
pdflib p = null;
int i, col, table, tf;
final double llx = 25, lly = 50, urx = 825, ury = 550;
String result;
int exitcode = 0;
String header[] = {
"Language",
"Raw input",
"Reordered and shaped output"
};
class shaping {
shaping(String fontopt, String optlist, boolean textflow,
String language, String text) {
this.fontopt = fontopt;
this.optlist = optlist;
this.textflow = textflow;
this.language = language;
this.text = text;
}
String fontopt; /* fontname and other font options */
String optlist; /* text options */
boolean textflow; /* can't use Textflow for Bidi text */
String language; /* language name */
String text; /* sample text */
}
shaping shapingsamples[] = {
/* -------------------------- Arabic -------------------------- */
new shaping(
"fontname=NotoNaskhArabic-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=arab", false,
"Arabic",
"\u0627\u0644\u0639\u064E\u0631\u064E\u0628\u0650\u064A\u0629"),
new shaping(
"fontname=NotoNaskhArabic-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=arab", false,
"Arabic",
"\u0645\u0631\u062D\u0628\u0627! (Hello)"),
new shaping(
"fontname=NotoNaskhArabic-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=arab",
false,
"Arabic",
"\uFEFF\u0627\u0644\u0645\u0627\u062F\u0629\u0020"
+ "\u0031\u0020\u064A\u0648\u0644\u062F\u0020\u062C"
+ "\u0645\u064A\u0639\u0020\u0627\u0644\u0646\u0627"
+ "\u0633\u0020\u0623\u062D\u0631\u0627\u0631\u064B"
+ "\u0627\u0020\u0645\u062A\u0633\u0627\u0648\u064A"
+ "\u0646\u0020\u0641\u064A\u0020\u0627\u0644\u0643"
+ "\u0631\u0627\u0645\u0629\u0020\u0648\u0627\u0644"
+ "\u062D\u0642\u0648\u0642\u002E\u0020"),
new shaping(
"fontname=NotoNaskhArabic-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=arab",
false,
"Arabic",
"\u0648\u0642\u062F\u0020\u0648\u0647\u0628\u0648"
+ "\u0627\u0020\u0639\u0642\u0644\u0627\u064B\u0020"
+ "\u0648\u0636\u0645\u064A\u0631\u064B\u0627\u0020"
+ "\u0648\u0639\u0644\u064A\u0647\u0645\u0020\u0623"
+ "\u0646\u0020\u064A\u0639\u0627\u0645\u0644\u0020"
+ "\u0628\u0639\u0636\u0647\u0645\u0020\u0628\u0639"
+ "\u0636\u064B\u0627\u0020\u0628\u0631\u0648\u062D"
+ "\u0020\u0627\u0644\u0625\u062E\u0627\u0621\u002E"),
/* -------------------------- Hebrew -------------------------- */
new shaping(
"fontname=NotoSerifHebrew-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=hebr", false, "Hebrew",
"\u05E2\u05B4\u05D1\u05B0\u05E8\u05B4\u05D9\u05EA"),
new shaping(
"fontname=NotoSerifHebrew-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=hebr",
false,
"Hebrew",
"\u05E1\u05E2\u05D9\u05E3\u0020\u05D0\u002E\u0020"
+ "\u05DB\u05DC\u0020\u05D1\u05E0\u05D9\u0020\u05D0"
+ "\u05D3\u05DD\u0020\u05E0\u05D5\u05DC\u05D3\u05D5"
+ "\u0020\u05D1\u05E0\u05D9\u0020\u05D7\u05D5\u05E8"
+ "\u05D9\u05DF\u0020\u05D5\u05E9\u05D5\u05D5\u05D9"
+ "\u05DD\u0020\u05D1\u05E2\u05E8\u05DB\u05DD\u0020"
+ "\u05D5\u05D1\u05D6\u05DB\u05D5\u05D9\u05D5\u05EA"
+ "\u05D9\u05D4\u05DD\u002E\u0020"),
new shaping(
"fontname=NotoSerifHebrew-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=hebr",
false,
"Hebrew",
"\u05DB\u05D5\u05DC\u05DD\u0020\u05D7\u05D5\u05E0"
+ "\u05E0\u05D5\u0020\u05D1\u05EA\u05D1\u05D5\u05E0"
+ "\u05D4\u0020\u05D5\u05D1\u05DE\u05E6\u05E4\u05D5"
+ "\u05DF\u002C\u0020"),
new shaping(
"fontname=NotoSerifHebrew-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=hebr",
false,
"Hebrew",
"\u05DC\u05E4\u05D9\u05DB\u05DA\u0020\u05D7\u05D5"
+ "\u05D1\u05D4\u0020\u05E2\u05DC\u05D9\u05D4\u05DD"
+ "\u0020\u05DC\u05E0\u05D4\u05D5\u05D2\u0020\u05D0"
+ "\u05D9\u05E9\u0020\u05D1\u05E8\u05E2\u05D4\u05D5"
+ "\u0020\u05D1\u05E8\u05D5\u05D7\u0020\u05E9\u05DC"
+ "\u0020\u05D0\u05D7\u05D5\u05D4\u002E"),
/* -------------------------- Hindi -------------------------- */
new shaping(
"fontname=NotoSerifDevanagari-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=deva", true, "Hindi",
"\u0939\u093F\u0928\u094D\u0926\u0940"),
new shaping(
"fontname=NotoSerifDevanagari-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=deva advancedlinebreak",
true,
"Hindi",
"\u0905\u0928\u0941\u091A\u094D\u091B\u0947\u0926"
+ "\u0020\u0967\u002E\u0020\u0938\u092D\u0940\u0020"
+ "\u092E\u0928\u0941\u0937\u094D\u092F\u094B\u0902"
+ "\u0020\u0915\u094B\u0020\u0917\u094C\u0930\u0935"
+ "\u0020\u0914\u0930\u0020\u0905\u0927\u093F\u0915"
+ "\u093E\u0930\u094B\u0902\u0020\u0915\u0947\u0020"
+ "\u092E\u093E\u092E\u0932\u0947\u0020\u092E\u0947"
+ "\u0902\u0020\u091C\u0928\u094D\u092E\u091C\u093E"
+ "\u0924\u0020\u0938\u094D\u0935\u0924\u0928\u094D"
+ "\u0924\u094D\u0930\u0924\u093E\u0020\u0914\u0930"
+ "\u0020\u0938\u092E\u093E\u0928\u0924\u093E\u0020"
+ "\u092A\u094D\u0930\u093E\u092A\u094D\u0924\u0020"
+ "\u0939\u0948\u0020\u0964\u0020\u0909\u0928\u094D"
+ "\u0939\u0947\u0902\u0020\u092C\u0941\u0926\u094D"
+ "\u0918\u093F\u0020\u0914\u0930\u0020\u0905\u0928"
+ "\u094D\u0924\u0930\u093E\u0924\u094D\u092E\u093E"
+ "\u0020\u0915\u0940\u0020\u0926\u0947\u0928\u0020"
+ "\u092A\u094D\u0930\u093E\u092A\u094D\u0924\u0020"
+ "\u0939\u0948\u0020\u0914\u0930\u0020\u092A\u0930"
+ "\u0938\u094D\u092A\u0930\u0020\u0909\u0928\u094D"
+ "\u0939\u0947\u0902\u0020\u092D\u093E\u0908\u091A"
+ "\u093E\u0930\u0947\u0020\u0915\u0947\u0020\u092D"
+ "\u093E\u0935\u0020\u0938\u0947\u0020\u092C\u0930"
+ "\u094D\u0924\u093E\u0935\u0020\u0915\u0930\u0928"
+ "\u093E\u0020\u091A\u093E\u0939\u093F\u090F\u0020"
+ "\u0964"),
/* -------------------------- Sanskrit -------------------------- */
new shaping(
"fontname=NotoSerifDevanagari-Regular fallbackfonts={ {fontname=NotoSerif-Regular} }",
"shaping script=deva", true, "Sanskrit",
"\u0938\u0902\u0938\u094D\u0915\u0943\u0924\u092E"
+ "\u094D")
};
try {
p = new pdflib();
p.set_option("searchpath={" + searchpath + "}");
/*
* This means that formatting and other errors will raise an
* exception. This simplifies our sample code, but is not
* recommended for production code.
*/
p.set_option("errorpolicy=exception");
/* Set an output path according to the name of the topic */
if (p.begin_document(outfile, "") == -1) {
throw new Exception("Error: " + p.get_errmsg());
}
p.set_info("Creator", "PDFlib starter sample");
p.set_info("Title", "starter_shaping");
table = -1;
/* Create table header */
for (col = 0; col < header.length; col++) {
optlist =
"fittextline={fontname=NotoSerif-Bold encoding=winansi "
+ "fontsize=14} colwidth=" + (col == 0 ? "10%" : "45%");
table = p.add_table_cell(table, col + 1, 1, header[col],
optlist);
}
/* Create shaping samples */
for (i = 0; i < shapingsamples.length; i++) {
final shaping sample = shapingsamples[i];
col = 1;
final int row = i + 2;
/* Column 1: language name */
optlist = "fittextline={fontname=NotoSerif-Regular "
+ "fontsize=12}";
table = p.add_table_cell(table, col++, row, sample.language,
optlist);
/* Column 2: raw text */
optlist =
sample.fontopt
+ " fontsize=12 leading=150% alignment=left";
tf = p.create_textflow(sample.text, optlist);
optlist = "margin=4 fittextflow={verticalalign=top} textflow="
+ tf;
table = p.add_table_cell(table, col++, row, "", optlist);
/* Column 3: shaped and reordered text (Textline or Textflow) */
if (sample.textflow) {
optlist =
sample.fontopt + " " + sample.optlist
+ " fontsize=12 leading=150% alignment=left";
tf = p.create_textflow(sample.text, optlist);
optlist =
"margin=4 fittextflow={verticalalign=top} textflow="
+ tf;
table = p.add_table_cell(table, col++, row, "", optlist);
}
else {
optlist =
"fittextline={" + sample.fontopt + " " + sample.optlist
+ " fontsize=12 }";
table = p.add_table_cell(table, col++, row, sample.text,
optlist);
}
}
/* ---------- Place the table on one or more pages ---------- */
/*
* Loop until all of the table is placed; create new pages as long
* as more table instances need to be placed.
*/
do {
p.begin_page_ext(0, 0, "width=a4.height height=a4.width");
/* Shade every other row; draw lines for all table cells. */
optlist = "header=1 fill={{area=rowodd "
+ "fillcolor={gray 0.9}}} stroke={{line=other}} ";
/* Place the table instance */
result = p.fit_table(table, llx, lly, urx, ury, optlist);
if (result.equals("_error")) {
throw new Exception("Couldn't place table: "
+ p.get_errmsg());
}
p.end_page_ext("");
}
while (result.equals("_boxfull"));
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);
}
}
}