/* $Id: starter_opentype.java,v 1.1 2009/09/30 14:31:52 stm Exp $
 * 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 8
 * 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_parameter("SearchPath", searchpath);
            p.set_parameter("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_parameter("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.1 $");

            /* 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();
            }
        }
    }
}

