fonts/glyph_availability
Check the availability of glyphs in a font.
Download Java Code Switch to PHP Code Show Output
/*
* Glyph availability: Check the availability of glyphs in a font
*
* Load a font with "encoding=unicode" (default). Then, for a specific Unicode
* character, output a row in a table containing the following information:
*
* 1) Font name
* 2) Unicode code point and character name
* 3) Glyph if available in the font
* 4) Glyph name if available in the font
*
* Required software: PDFlib/PDFlib+PDI/PPS 10
* Required data: Font files
*/
package com.pdflib.cookbook.pdflib.fonts;
import com.pdflib.pdflib;
import com.pdflib.PDFlibException;
class glyph_availability {
static private class testcase {
testcase(String font_name, String font_optlist,
String character, String character_desc) {
this.font_name = font_name;
this.font_optlist = font_optlist;
this.character = character;
this.character_desc = character_desc;
}
String font_name;
String font_optlist;
String character;
String character_desc;
}
public static void main(String argv[]) {
/* This is where the data files are. Adjust as necessary. */
final String searchpath = "../input";
String outfile = "glyph_availability.pdf";
String title = "Glyph Availability";
String optlist;
pdflib p = null;
int i, table;
final double llx = 50, lly = 50, urx = 800, ury = 550;
String result;
int exitcode = 0;
final String headers[] = { "Font name", "Unicode character",
"Glyph", "Glyph name" };
final testcase testcases[] = {
new testcase("NotoSerif-Regular", "", "a", "U+0061 LATIN LETTER A"),
new testcase("NotoSerif-Regular", "", "\u20AC", "U+20AC EURO SIGN"),
new testcase("NotoSerif-Regular", "", "\u017A", "U+017A LATIN SMALL LETTER Z WITH ACUTE"),
new testcase("NotoSerif-Regular", "", "\u2D33", "U+2D33 TIFINAGH LETTER YAG"),
new testcase("NotoNaskhArabic-Regular", "fallbackfonts={ {fontname=NotoSerif-Regular} }",
"\u0646", "U+0646 ARABIC LETTER NOON"),
new testcase("NotoNaskhArabic-Regular", "fallbackfonts={ {fontname=NotoSerif-Regular} }",
"\u017A", "U+017A LATIN SMALL LETTER Z WITH ACUTE"),
/*
* Demonstration of Unicode characters beyond U+FFFF. The Unicode
* character U+2000B (surrogate representation \uD840\DC0B) is
* checked using a CJK font. The surrogates are resolved
* by the Java compiler.
* Languages which don't support surrogates or backslash syntax for
* characters outside the BMP must use PDFlib character references
* instead, e.g. 𠀋
*/
new testcase("NotoSerifCJKjp-Regular", "", "\uD840\uDC0B",
"U+2000B CJK UNIFIED IDEOGRAPH"),
};
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 Cookbook");
p.set_info("Title", title);
table = -1;
/* Table header */
optlist = "fittextline={fontname=NotoSerif-Bold "
+ "fontsize=12} margin=4";
for (i = 0; i < headers.length; i++) {
table = p.add_table_cell(table, i + 1, 1, headers[i], optlist);
}
/* Create a table with feature samples, one feature per table row */
for (i = 0; i < testcases.length; i++) {
final testcase testcase = testcases[i];
final int row = i + 2;
/*
* Try to load the fonts, output a row that shows the missing
* font if a font can't be loaded.
*/
final String error_optlist = "fittextline={fontname=NotoSerif-Regular "
+ "fontsize=12 fillcolor=red} "
+ "margin=4";
final String font_optlist = testcase.font_optlist
+ " errorpolicy=return";
final int font = p.load_font(testcase.font_name, "unicode",
font_optlist);
if (font != -1) {
table = put_row(p, table, row, font, testcase);
}
else {
table = p.add_table_cell(table, 1, row,
testcase.font_name + ": font not available",
error_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);
}
}
/**
* Output one row with information regarding one specific character
*
* @param p
* the pdflib object
* @param table
* the table handle
* @param row
* the number of the current row
* @param font
* the font handle for the original font
* @param t
* the current test case
*
* @return the table handle
*
* @throws PDFlibException
* @throws Exception
*/
static int put_row(pdflib p, int table, int row, int font, testcase t)
throws PDFlibException, Exception {
int col = 1;
/*
* Common option list for all columns except the "Actual glyph" column
*/
final String common_optlist = "fittextline={fontname=NotoSerif-Regular "
+ "fontsize=12} margin=4";
/*
* Column 1: Font name
*/
table = p.add_table_cell(table, col++, row, t.font_name, common_optlist);
/*
* Column 2: Unicode character
*/
table = p.add_table_cell(table, col++, row, t.character_desc, common_optlist);
/* The data type "Unichar" in option lists expects character references
* without the &...; decoration, while the decoration is required in
* text output functions.
* We don't use charrefs in the examples, but if you need them and
* want to pass them e.g. to info_font() you can resolve charrefs
* as follows:
*
* String t_plain = p.convert_to_unicode("utf16",
* t.character.getBytes("UTF-16"),
* "outputformat=utf16 charref=true");
*
* Conversion from UTF-16 to UTF-16 may look a bit silly, but we use
* the convert_to_unicode() method to resolve character references.
* The result can be used in both option lists and text output functions.
* This is only required if character references are used in the text.
*/
/*
* Determine whether a glyph is available, and if so, determine
* the glyph name, if available.
*/
final int gid = (int) p.info_font(font, "glyphid", "unicode=" + t.character);
String display_character;
String gn;
if (gid != -1) {
display_character = t.character;
final int gn_idx = (int) p.info_font(font, "glyphname",
"unicode=" + t.character);
if (gn_idx != -1) {
gn = p.get_string(gn_idx, "");
}
else {
gn = "n/a";
}
}
else {
display_character = "n/a";
gn = "n/a";
}
/*
* Column 3: Actual glyph, if available.
*/
final String testfont_optlist = "fittextline={font=" + font
+ " fontsize=12} margin=4";
table = p.add_table_cell(table, col++, row, display_character,
testfont_optlist);
/*
* Column 4: Glyph name
*/
table = p.add_table_cell(table, col++, row, gn, common_optlist);
return table;
}
}