fonts/opentype_features_for_cjk
Demonstrate the use of OpenType features for CJK fonts and text.
Download Java Code Switch to PHP Code Show Output
/*
* Demonstrate OpenType font features for Chinese, Japanese, and Korean text
*
* Demonstrate various CJK OpenType features after checking
* whether a particular feature is supported in a font.
*
* Required software: PDFlib/PDFlib+PDI/PPS 10
* Required data: CJK font with OpenType CJK features
*
* Note that even if a particular OpenType feature is present in the font
* it may not necessarily affect the characters provided in the test strings
* below. In this case you must replace the test strings with content which
* is suited to your font.
*/
package com.pdflib.cookbook.pdflib.fonts;
import com.pdflib.pdflib;
import com.pdflib.PDFlibException;
class opentype_features_for_cjk {
public static void main(String argv[]) {
/* This is where the data files are. Adjust as necessary. */
final String searchpath = "../input";
final String outfile = "opentype_features_for_cjk.pdf";
String optlist;
pdflib p = null;
int i, table, font;
final double llx = 25, lly = 20, urx = 825, ury = 580;
String result;
int exitcode = 0;
final String testfont = "NotoSerifCJKjp-Regular";
final String headers[] = { "Description", "Option list",
"Font name", "Raw input (feature disabled)", "Feature enabled" };
class testcase {
testcase(String description, String optlist,
String feature, String text) {
this.description = description;
this.optlist = optlist;
this.feature = feature;
this.text = text;
}
String description;
String optlist;
String feature;
String text;
}
final testcase testcases[] = {
new testcase("Localized forms for simplified Chinese",
"features={locl} script=hang language=ZHS", "locl",
"\u2E95\u2EDD\u38C0"),
new testcase("Localized forms for traditional Chinese",
"features={locl} script=hang language=ZHT", "locl",
"\u328B\u35EB\u3B35"),
new testcase("Localized forms for Korean",
"features={locl} script=hang language=KOR", "locl",
"\u4E73\u52E4\u52FB"),
new testcase("Simplified forms",
"features={smpl}", "smpl",
"\u6AAF \u81FA \u98B1"),
new testcase("Traditional forms",
"features={trad}", "trad",
"\u53F0\u4E03\u4E0E\u4E31\u7D1B\u9912\u96B8" +
"\u9698\u966A\u939A"),
new testcase("Expert forms",
"features={expt}", "expt",
"\u5516\u82A6\u98F4\u9E78\u9D60\u6F23\u84EE\u7BDD"),
new testcase("Full widths",
"features={fwid}", "fwid",
"0123-456(789)=25"),
new testcase("Horizontal kana alternates",
"features={hkna}", "hkna",
"\u3041\u3042\u3043\u3044 \u30A1\u30A2\u30A3" +
"\u30A4\u30E5\u30E4\u30B4\u30A7"),
new testcase("Hangul",
"features={hngl}", "hngl",
"\u4F3D"),
new testcase("Hojo kanji forms (JIS X 0212-1990)",
"features={hojo}", "hojo",
"\u6FF9\u9B35\u8200\u9CE6\u9B2D\u9721\u884B"),
new testcase("Half widths",
"features={hwid}", "hwid",
"0123-456(789)=25"),
new testcase("Italics",
"features={ital}", "ital",
"ABCD abcd 1234"),
new testcase("JIS2004 forms",
"features={jp04}", "jp04",
"\u9022\u98F4\u6EA2\u8328\u9C2F\u6DEB\u8FC2"),
new testcase("JIS78 forms",
"features={jp78}", "jp78",
"\u5516\u53F1\u63B4\u8000"),
new testcase("JIS83 forms",
"features={jp83}", "jp83",
"\u4E08\u51A4"),
new testcase("JIS90 forms",
"features={jp90}", "jp90",
"\u5026\u6994"),
new testcase("Alternate annotation forms",
"features={nalt}", "nalt",
"ABC123\u002F\u30B4\u217B\u4E0B\u7981\u2F29\u4E2D\u2F42"),
new testcase("NLC kanji forms",
"features={nlck}", "nlck",
"\u4FA0\u64B9"),
new testcase("Proportional kana",
"features={pkna}", "pkna",
"\u3041\u3042 \u30A1\u30A2 \uFF66 \uFF67"),
new testcase("Proportional widths",
"features={pwid}", "pwid",
"\u3041\u3042 \u30A1\u30A2 \u301C\uFF21\uFF23\uFF28" +
"\uFF29\uFF2D ABCD abcd 1234"),
new testcase("Quarter widths",
"features={qwid}", "qwid",
"0123-456(789)=25"),
new testcase("Ruby notation forms",
"features={ruby}", "ruby",
"\u3042\u304A\u307D\u30AA\u30BC\u30F1\u25C9\u31F0\u31FF"),
new testcase("Traditional name forms",
"features={tnam}", "tnam",
"\u4E9C"),
new testcase("Third widths",
"features={twid}", "twid",
"0123-456(789)=25"),
new testcase("Vertical kana alternates",
"vertical features={vkna}", "vkna",
"\u3041\u3042\u3043\u3044\u31FF\u31F8\u30CB\u30BB"),
// "vrt2" and "vert" are activated automatically in vertical mode
new testcase("Vertical alternates and rotation (vrt2)",
"vertical", "vrt2",
"\uFF08ab\uFF09\uFF1A\u300Cab\u300D\u3348"),
new testcase("Vertical alternates (vert)",
"vertical", "vert",
"\uFF08ab\uFF09\uFF1A\u300Cab\u300D\u3348"),
};
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 Cookbook");
p.set_info("Title", "opentype_features_for_cjk");
table = -1;
/* Table header */
for (i = 0; i < headers.length; i++) {
final int col = i + 1;
optlist =
"fittextline={fontname=NotoSerif-Bold 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;
int col = 1;
/* Common option list for columns 1-3 */
optlist =
"fittextline={fontname=NotoSerif-Regular fontsize=12} "
+ "margin=4";
/* Column 1: feature description */
table = p.add_table_cell(table, col++, row,
testcase.description, optlist);
/* Column 2: option list */
table = p.add_table_cell(table, col++, row, testcase.optlist,
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
+ "} fontsize=12} 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", "");
/* 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 = "margin=4 fittextline={fontname={" + testfont
+ "} fontsize=12 "
+ testcase.optlist + "}";
table = p.add_table_cell(table, col++, row, testcase.text,
optlist);
}
else {
/* feature is not available: emit a warning */
optlist = "fittextline={fontname=NotoSerif-Regular "
+ "fontsize=12 fillcolor=red} margin=4";
table = p.add_table_cell(table, col++, row,
"(feature not available in this font)", optlist);
}
}
/*
* 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");
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);
}
}
}