PDFlib Cookbook

cookbook

complex_scripts/arabic_formatting

Download Java Code       Switch to PHP code     Show Output PDF

/* $Id: arabic_formatting.java,v 1.12 2017/01/26 13:11:54 stm Exp $
 * Starter sample for Arabic text formatting
 * Demonstarte various formatting topic specific for the Arabic script;
 * Additional aspects are demonstrated in the bidi_formatting Cookbook topic.
 * 
 * Required software: PDFlib/PDFlib+PDI/PPS 9
 * Required data: Arabic fonts
 * 
 * The code below uses the ScheherazadeRegOT font (included in the Cookbook
 * package), the font "Tahoma" and the "Arial Unicode MS" font from Microsoft.
 * For using the latter two fonts, put the respective font files "tahoma.ttf"
 * and "arialuni.ttf" into the "extra_input" directory. Alternatively, if you 
 * have the fonts installed as host fonts, you can replace the lower-case names
 * with the host font names "Tahoma" and "Arial Unicode MS". Tahoma is available
 * by default on Windows systems.
 * 
 * This example is not run by default from the Ant build.xml file and can be
 * executed either specifically by invoking "ant arabic_formatting" or together
 * with the other topics that require extra configuration by invoking "ant
 * run-extra-topics".
 */

package com.pdflib.cookbook.pdflib.complex_scripts;

import com.pdflib.pdflib;
import com.pdflib.PDFlibException;

class arabic_formatting {
    public static void main(String argv[]) {
        /* This is where the data files are. Adjust as necessary. */
        final String searchpath = "../input";
        
        /*
         * Search path for extra resources, put "arialuni.ttf" and "tahoma.ttf"
         * here.
         */
        final String extra_searchpath = "../extra_input";
        final String outfile = "arabic_formatting.pdf";

        String optlist;
        pdflib p = null;
	int exitcode = 0;
        int i, col, table;
        final double llx = 50, lly = 50, urx = 800, ury = 550;
        String result;

        String header[] = { "Arabic formatting topic", "Raw input",
            "Reordered and shaped output" };

        class shaping {
            shaping(String fontname, String optlist,
                    String language, String text) {
                this.fontname = fontname;
                this.optlist = optlist;
                this.language = language;
                this.text = text;
            }

            String fontname; /* name of the font for this script */
            String optlist; /* text options */
            String language; /* language name */
            String text; /* sample text */
        }

        shaping shapingsamples[] = {
        	new shaping(
                "ScheherazadeRegOT",
                "shaping script=arab",
                "Add vowels to base consonants",
                "\u0643\u0650\u062A\u064E\u0627\u0628"),
                
            new shaping(
                "ScheherazadeRegOT", "shaping script=arab charref",
                "Isolated form of HEH could be confused with digit FIVE (wrong)",
                "\u0661\u0663\u0666\u0665 \u0647"),
                        
            new shaping(
                "ScheherazadeRegOT", "shaping script=arab charref",
                "Force initial form of HEH with ZERO WIDTH JOINER",
                "\u0661\u0663\u0666\u0665 \u0647‍"),

            new shaping(
                "ScheherazadeRegOT", "shaping script=arab charref",
                "Persian plural with joined character (wrong)",
                "\u0645\u0648\u0632\u0647\u0647\u0627"),

            new shaping(
                "ScheherazadeRegOT", "shaping script=arab charref",
                "Prevent character join with ZERO WIDTH NON-JOINER",
                "\u0645\u0648\u0632\u0647‌\u0647\u0627"),
                
            new shaping(
                "ScheherazadeRegOT", "shaping script=arab charref",
                "Abbreviation with character join (wrong)",
                "\u0623\u064A\u0628\u064A\u0625\u0645"),

            new shaping(
                "ScheherazadeRegOT", "shaping script=arab charref",
                "Prevent character join with ZERO WIDTH NON-JOINER",
                "\u0623\u064A‌\u0628\u064A‌\u0625\u0645"),
                    
// The "Allah" ligature in Tahoma works only with Arabic presentation forms!
            new shaping(
                "tahoma",
                "shaping script=arab",
                "Without optional ligature",
                "\uFEDF\uFEE0\uFEEA"),

            new shaping(
                "tahoma",
                "shaping script=arab features={liga}",
                "With optional ligature: features={liga}",
                "\uFEDF\uFEE0\uFEEA"),

            new shaping(
                "ScheherazadeRegOT",
                "shaping script=arab",
                "European digits",
                "0123456789"),

            new shaping(
                "ScheherazadeRegOT",
                "shaping script=arab",
                "Arabic-Indic digits",
                "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669"),

            new shaping(
                "arialuni",
                "shaping script=arab features={locl} language=URD",
                "Variant figures for Urdu: features={locl} language=URD",
                "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669"),
                        
            new shaping(
                "ScheherazadeRegOT",
                "shaping script=arab",
                "Text without elongation",
                "\u062D\u0642\u0648\u0642 " +
                "\u0627\u0644\u0627\u0646\u0633\u0627\u0646"),

            new shaping(
                "ScheherazadeRegOT",
                "shaping script=arab",
                "Tatweel (kashida) elongation",
                "\u062D\u0642\u0640\u0640\u0648\u0642 " +
                "\u0627\u0644\u0627\u0646\u0633\u0640\u0640\u0627\u0646"),

            new shaping(
                "ScheherazadeRegOT",
                "shaping script=arab",
                "More tatweel elongation",
                "\u062D\u0642\u0640\u0640\u0640\u0640\u0640\u0640\u0648\u0642 "+
                "\u0627\u0644\u0627\u0646\u0633" +
                "\u0640\u0640\u0640\u0640\u0640\u0640" +
                "\u0627\u0646"),

            new shaping(
                "ScheherazadeRegOT",
                "shaping script=arab",
                "Even more tatweel elongation",
                "\u062D\u0642" +
                "\u0640\u0640\u0640\u0640\u0640\u0640\u0640\u0640\u0640\u0640" +
                "\u0648\u0642 " +
                "\u0627\u0644\u0627\u0646\u0633" +
                "\u0640\u0640\u0640\u0640\u0640\u0640\u0640\u0640\u0640\u0640" +
                "\u0627\u0646"),
        };

        try {
            p = new pdflib();

            p.set_option("searchpath={" + searchpath + "}");
            p.set_option("searchpath={" + extra_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", "arabic_formatting $Revision: 1.12 $");

            table = -1;

            /* Create table header */
            for (col = 0; col < header.length; col++) {
                optlist =
                	"margin=4 " +
                    "fittextline={fontname=Helvetica-Bold encoding=winansi "
                    + "fontsize=14} colwidth=" + (col == 0 ? "50%" : "25%");
                table = p.add_table_cell(table, col + 1, 1, header[col],
                        optlist);
            }

            /* Create shaping samples */
            for (i = 0; i < shapingsamples.length; i++) {
                final shaping sample = shapingsamples[i];

                col = 1;
                final int row = i + 2;

                /* Column 1: description */
                optlist = "margin=4 fittextline={fontname=Helvetica "
            		+ "encoding=unicode fontsize=12 position={left center}}";
                table = p.add_table_cell(table, col++, row, sample.language,
                        optlist);

                /* Column 2: raw text */
                optlist = "margin=4 fittextline={fontname={" + sample.fontname
                	+ "} encoding=unicode fontsize=18 position={left center}}";
                table = p.add_table_cell(table, col++, row, sample.text,
                		optlist);

                /* Column 3: shaped and reordered text */
                optlist =
                    "margin=4 fittextline={fontname={" + sample.fontname
                    + "} encoding=unicode fontsize=18 "
                    + sample.optlist + " position={right center}}";
                table = p.add_table_cell(table, col++, row, sample.text,
                        optlist);
            }

            /* ---------- 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.height height=a4.width");

                /* Shade every other row; draw lines for all table cells. */
                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.print("PDFlib exception occurred:\n");
            System.err.print("[" + e.get_errnum() + "] " + e.get_apiname()
                    + ": " + e.get_errmsg() + "\n");
	    exitcode = 1;
        }
        catch (Exception e) {
            System.err.println(e.getMessage());
	    exitcode = 1;
        }
        finally {
            if (p != null) {
                p.delete();
            }
	    System.exit(exitcode);
        }
    }
}