PDFlib Cookbook

cookbook

fonts/font_lister

Create a list of all fonts available in the 'searchpath' directories.

Download Java Code  Switch to PHP Code  Show Output 

/*
 * Font lister:
 * Create a list of all fonts available in the "searchpath" directories.
 * 
 * Also create a UPR file which can be used for PDFlib font configuration.
 * 
 * Required software: PDFlib/PDFlib+PDI/PPS 10
 * Required data: font file
 */

package com.pdflib.cookbook.pdflib.fonts;
import com.pdflib.pdflib;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;

import com.pdflib.PDFlibException;


public class font_lister {

    /* Helper function to detect subdirectories (not recursive) */
    public static File[] getSubDirectories(String dir){
        File[] directories = new File(dir).listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isDirectory();
            }
        });
        return directories;
    }
    public static void main (String argv[])
    {
        String outfile = "font_lister.pdf";
        String title = "Font Lister";
        ArrayList<String> fontdirectories = new ArrayList<String>();
        ArrayList<String> searchpathdirectory = new ArrayList<String>();
        ArrayList<String> fonts = new ArrayList<String>();

        /* Typical font directories on Linux systems */
        fontdirectories.add("/usr/share/fonts/");
        fontdirectories.add("/usr/share/fonts/truetype/");
        fontdirectories.add("/usr/share/fonts/opentype/");
        fontdirectories.add("/usr/local/share/fonts/");
        fontdirectories.add("/usr/local/share/fonts/truetype/");
        fontdirectories.add("/usr/local/share/fonts/opentype/");

        /* Typical font directory on macOS */
        fontdirectories.add("/Library/Fonts/");

        /* Typical font directory on Windows */
        fontdirectories.add("C:\\Windows\\Fonts");

        pdflib p = null;
        int fontresource = 0;
        int count=0;
        int row=1;
        int tbl = -1;
        int font;
        String optlist;
        String result;
        String resourceentry;
        final double llx = 50, lly = 50, urx = 550, ury = 800;
        final String text = "The quick brown fox jumps over the lazy dog";
        final String headeropt = 
            "fittextline {fontname {NotoSerif-Bold} fontsize=10}";
        int exitcode = 0;

        try {
            p = new pdflib();

            p.set_option("errorpolicy=exception");

            /* Get all subdirectories from input paths */
            for(int i=0; i< fontdirectories.size(); i++){
                searchpathdirectory.add(fontdirectories.get(i));
                File[] dirs = getSubDirectories(fontdirectories.get(i));
                if (dirs != null){
                    for (File dir: dirs){
                        searchpathdirectory.add(dir.getPath());
                    }
                }
            }
                    
            /* Add font directories to the search path */
            for (int i=0; i <searchpathdirectory.size(); i++) {
                p.set_option("searchpath={{" + searchpathdirectory.get(i) + "}}");
            }
           
            /* Enumerate all fonts on the searchpath and create a UPR file
             * with a mapping of font and file names
             */
            p.set_option("enumeratefonts saveresources={filename={font_lister_pdflib.upr}}");

            /* Retrieve the names of all enumerated fonts */
            do{
                fontresource = (int) p.get_option("FontOutline", "resourcenumber=" + ++count);
                if (fontresource == -1) { 
                    break;
                }
                resourceentry = p.get_string(fontresource, "");
                fonts.add(resourceentry.split(" = ")[0]);
            } while (fontresource != -1);

            /* Create output document */
            p.begin_document(outfile, "");

            p.set_info("Creator", "PDFlib Cookbook");
            p.set_info("Title", title);

            /* Add the Cookbook input directory which is required for the
             * NotoSerif-Bold font used in the table.
             */
            p.set_option("searchpath={../input}");

            /* create table header */
            tbl = p.add_table_cell(tbl, 1, 1, "Fontname", 
                "colwidth=150 margin=3 " + headeropt);
            tbl = p.add_table_cell(tbl, 2, 1, "Sample text", 
                "colwidth=350 margin=3 " + headeropt);

            if (!fonts.isEmpty()){
                for (int idx=0; idx< fonts.size(); idx++){
                    StringBuilder sampletext = new StringBuilder();
                    
                    font = p.load_font(fonts.get(idx), "unicode", "errorpolicy=return");
                    if (font ==-1){
                        /* Emit a warning if the font couldn't be loaded */
                        System.err.println("'" + fonts.get(idx) + 
                            "'' skipped. load_font() failed: [" + p.get_errnum() + 
                            "] " + p.get_errmsg());
                        continue;
                    }
                    row++;
                    tbl = p.add_table_cell(tbl, 1, row, fonts.get(idx), 
                        "fittextline {fontname {NotoSerif-Regular} " +
                        "fontsize=10 position {left top}} margin=3");

                    /* Emit sample text for text fonts. If we have a symbol
                     * font or a font which contains only very few glyphs
                     * we emit the first available glyphs.
                     */
                    if (p.info_font(font, "symbolfont", "") == 1  || 
                        p.info_textline(text, "unknownchars", 
                            "font=" + font + " fontsize=10") >10){
                       /* Retrieve Unicode values for the first few glyphs and 
                        * build a sample text string.
                        */
                        for (int i = 1; i <= 20; i++){
                            int uv = (int) p.info_font(font, "unicode", "glyphid=" + i);
                            sampletext.append( "&#" + uv + ";");
                        }
                    }else{
                        sampletext.append(text);
                    }
                    int tf = p.add_textflow(-1, sampletext.toString(), "font=" + font + 
                        " fontsize=12 charref");
                    tbl = p.add_table_cell(tbl, 2, row, "", "margin=3 textflow=" + tf);

                } 
            } else {
                tbl = p.add_table_cell(tbl, 1, 2, "No fonts have been found.",
                    "fittextline {fontname {NotoSerif-Regular} " +
                    "fontsize=10 position {left top}} margin=3 colspan=2");
            }
            /* ---------- 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.width height=a4.height");

                /*
                 * Shade every other row; draw lines for all table cells. Add
                 * "showcells showborder" to visualize cell borders
                 */
                optlist = "header=1 rowheightdefault=auto "
                    + "fill={{area=rowodd fillcolor={gray 0.9}}} "
                    + "stroke={{line=other}} ";

                /* Place the table instance */
                result = p.fit_table(tbl, 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"));

            /* Check the result; "_stop" means all is ok. */
            if (!result.equals("_stop")) {
                if (result.equals("_error")) {
                    throw new Exception("Error when placing table: "
                        + p.get_errmsg());
                }
                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 found in table");
                }
            }

            /* This will also delete Textflow handles used in the table */
            p.delete_table(tbl, "");

            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) {
            e.printStackTrace();
            System.err.println(e);
            exitcode = 1;
        } finally {
            if (p != null) {
                p.delete();
            }
            System.exit(exitcode);
        }
    }
        
}