* Starter sample for OpenType font features
*
* Demonstrate various typographic OpenType features after checking
* whether a particular feature is supported in a font.
*
* Required software: PDFlib/PDFlib+PDI/PPS 9
* Required data: suitable fonts with OpenType feature tables
*
* This sample uses a default font which includes a few features.
* For better results you should replace the default font with a suitable
* commercial font. Depending on the implementation of the features you
* may also have to replace the sample text below.
*
* Some ideas for suitable test fonts:
* Palatino Linotype: standard Windows font with many OpenType features
*/
package com.pdflib.cookbook.pdflib.fonts;
import com.pdflib.pdflib;
import com.pdflib.PDFlibException;
class starter_opentype {
public static void main(String argv[]) {
/* This is where the data files are. Adjust as necessary. */
final String searchpath = "../input";
final String outfile = "starter_opentype.pdf";
String optlist;
pdflib p = null;
int i, table, font;
final double llx = 50, lly = 50, urx = 800, ury = 550;
String result;
/* This font will be used unless another one is specified in the table */
final String defaulttestfont = "DejaVuSerif";
final String headers[] = { "OpenType feature", "Option list",
"Font name", "Raw input (feature disabled)", "Feature enabled" };
class testcase {
testcase(String description, String fontname, String feature,
String text) {
this.description = description;
this.fontname = fontname;
this.feature = feature;
this.text = text;
}
String description;
/* the default test font above will be used if this string is empty */
String fontname;
String feature;
String text;
}
final testcase testcases[] = {
new testcase("ligatures", "", "liga", "ff fi fl ffi ffl"),
new testcase("discretionary ligatures", "", "dlig", "st c/o"),
new testcase("historical ligatures", "", "hlig",
"&.longs;b &.longs;t"),
new testcase("small capitals", "", "smcp", "PostScript"),
new testcase("ordinals", "", "ordn", "1o 2a 3o"),
new testcase("fractions", "", "frac", "1/2 1/4 3/4"),
new testcase("alternate fractions", "", "afrc", "1/2 1/4 3/4"),
new testcase("slashed zero", "", "zero", "0"),
new testcase("historical forms", "", "hist", "s"),
new testcase("proportional figures", "", "pnum", "0123456789"),
new testcase("old-style figures", "", "onum", "0123456789"),
new testcase("lining figures", "", "lnum", "0123456789"),
new testcase("superscript", "", "sups", "0123456789") };
try {
p = new pdflib();
p.set_option("searchpath={" + searchpath + "}");
p.set_option("charref=true");
/*
* 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_opentype $Revision: 1.3 $");
/* Start Page */
p.begin_page_ext(0, 0, "width=a4.height height=a4.width");
table = -1;
/* Table header */
for (i = 0; i < headers.length; i++) {
final int col = i + 1;
optlist =
"fittextline={fontname=Helvetica-Bold encoding=unicode fontsize=12} "
+ "margin=4";
table = p.add_table_cell(table, col, 1, headers[i], optlist);
}
/* Create a table with feature samples, one feature per table row */
for (i = 0; i < testcases.length; i += 1) {
final testcase testcase = testcases[i];
final int row = i + 2;
/*
* Use the entry in the test table if available, and the default
* test font otherwise. This way we can easily check a font for
* all features, as well as insert suitable fonts for individual
* features.
*/
final String testfont =
testcase.fontname.length() > 0
? testcase.fontname
: defaulttestfont;
int col = 1;
/* Common option list for columns 1-3 */
optlist =
"fittextline={fontname=Helvetica encoding=unicode fontsize=12} "
+ "margin=4";
/* Column 1: feature description */
table = p.add_table_cell(table, col++, row,
testcase.description, optlist);
/* Column 2: option list */
final String buf = "features={" + testcase.feature + "}";
table = p.add_table_cell(table, col++, row, buf, optlist);
/* Column 3: font name */
table = p.add_table_cell(table, col++, row, testfont, optlist);
/* Column 4: raw input text with feature disabled */
optlist = "fittextline={fontname={" + testfont
+ "} encoding=unicode fontsize=12 embedding} margin=4";
table = p.add_table_cell(table, col++, row, testcase.text,
optlist);
/*
* Column 5: text with enabled feature, or warning if the
* feature is not available in the font
*/
font = p.load_font(testfont, "unicode", "embedding");
/* Check whether font contains the required feature table */
optlist = "name=" + testcase.feature;
if (p.info_font(font, "feature", optlist) == 1) {
/* feature is available: apply it to the text */
optlist = "fittextline={fontname={" + testfont
+ "} encoding=unicode fontsize=12 embedding "
+ "features={" + testcase.feature + "}} margin=4";
table = p.add_table_cell(table, col++, row, testcase.text,
optlist);
}
else {
/* feature is not available: emit a warning */
optlist = "fittextline={fontname=Helvetica encoding=unicode "
+ "fontsize=12 fillcolor=red} margin=4";
table = p.add_table_cell(table, col++, row,
"(feature not available in this font)", optlist);
}
}
/* Place the table */
optlist = "header=1 fill={{area=rowodd "
+ "fillcolor={gray 0.9}}} stroke={{line=other}} ";
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("");
p.end_document("");
}
catch (PDFlibException e) {
System.err.print("PDFlib exception occurred:\n");
System.err.print("[" + e.get_errnum() + "] " + e.get_apiname()
+ ": " + e.get_errmsg() + "\n");
}
catch (Exception e) {
System.err.println(e.getMessage());
}
finally {
if (p != null) {
p.delete();
}
}
}
}