BASKET
Search
PDFlib

/* $Id: clone_pdfx.java,v 1.11 2016/11/22 22:52:25 tm Exp $

 *

 * Clone PDF/A, PDF/UA and PDF/X standard documents

 * This is useful as basis for additional processing,

 * such as stamping, adding XMP metadata, adding page content, etc.

 *

 * The following aspects of the input document are cloned:

 * - PDF/A, PDF/UA and PDF/X version

 * - PDF/A or PDF/X output intent (if present)

 * - document language (if present)

 * - all pages including page geometry, i.e. page boxes and Rotate key

 * - the structure elements (tags); if required, an additional

 *   tag is inserted on top of the imported page elements

 * - XMP document metadata

 *

 * To demonstrate coordinate transformations which may be required

 * to add new page content this topic adds a stamp across all pages.

 *

 * Input documents may conform to any combination of PDF/A, PDF/UA

 * and PDF/X simultaneously.

 *

 * Note: Except for the names of the input and output documents the three

 * Cookbook topics clone_pdfa, clone_pdfua and clone_pdfx are exact copies.

 * They are included multiply so that they can easily be found in the

 * PDF/A, PDF/UA and PDF/X categories.

 *

 * required software: PDFlib/PDFlib+PDI/PPS 9 (9.1 for PDF/X-5n)

 * required data: PDF/A, PDF/UA or PDF/X input document

 */


package com.pdflib.cookbook.pdflib.pdfx;


import com.pdflib.pdflib;

import com.pdflib.PDFlibException;


public class clone_pdfx {

    public static void main(String argv[]) {

        /* This is where the data files are. Adjust as necessary. */

        String searchpath = "../input";


        pdflib p = null;

       

        String pdfinputfile = "PLOP-datasheet-PDFX-4.pdf";

        String title = "clone_pdfx";

       

        String pdfaversion, pdfuaversion, pdfxversion, inputlang;

        boolean taggedinput;

        String optlist = "";

        byte xmp[];


        /* The following standard flavors can be cloned: */

        String supportedflavors[] = {

            "PDF/A-1a:2005", "PDF/A-1b:2005",

            "PDF/A-2a", "PDF/A-2b", "PDF/A-2u",

            "PDF/A-3a", "PDF/A-3b", "PDF/A-3u",

               

            "PDF/X-1a:2003",

            "PDF/X-3:2003",

            "PDF/X-4", "PDF/X-4p",

            "PDF/X-5g", "PDF/X-5pg", "PDF/X-5n",

           

            "PDF/UA-1",

            "none",

        };


        int indoc, endpage, pageno, i;

        double x, y, phi, width, height;

        int exitcode = 0;


        try {

            p = new pdflib();


            p.set_option("searchpath={" + searchpath + "}");


            /* This means we must check return values of load_font() etc. */

            p.set_option("errorpolicy=return");


            /*

             * Open the input PDF, preserve tags if present (for cloning

             * PDF/A-1/2/3a and PDF/UA)

             */

            indoc = p.open_pdi_document(pdfinputfile, "usetags=true");

            if (indoc == -1) {

                throw new Exception("Error: " + p.get_apiname() + ": "

                    + p.get_errmsg());

            }


            /*

             * Read PDF/A, PDF/UA and PDF/X version of the input document

             */

            pdfaversion = p.pcos_get_string(indoc, "pdfa");

            pdfuaversion = p.pcos_get_string(indoc, "pdfua");

            pdfxversion = p.pcos_get_string(indoc, "pdfx");


            for (i = 0; i < supportedflavors.length; i++) {

                if (pdfaversion.equals(supportedflavors[i])) {

                    optlist += " pdfa=" + pdfaversion;

                    break;

                }

            }

            if (i == supportedflavors.length)

                System.err.println("Error: Cannot clone " + pdfaversion

                    + " documents");


            for (i = 0; i < supportedflavors.length; i++) {

                if (pdfuaversion.equals(supportedflavors[i])) {

                    optlist += " pdfua=" + pdfuaversion;

                    break;

                }

            }

            if (i == supportedflavors.length)

                System.err.println("Error: Cannot clone " + pdfuaversion

                    + " documents");


            for (i = 0; i < supportedflavors.length; i++) {

                if (pdfxversion.equals(supportedflavors[i])) {

                    optlist += " pdfx=" + pdfxversion;

                    break;

                }

            }

            if (i == supportedflavors.length)

                System.err.println("Error: Cannot clone " + pdfxversion

                    + " documents");


            /*

             * Read language entry of the input document if present

             */


            if (p.pcos_get_string(indoc, "type:/Root/Lang").equals("string")) {

                inputlang = p.pcos_get_string(indoc, "/Root/Lang");

                optlist += " lang=" + inputlang;

            }

            else

                inputlang = "";


            /*

             * Clone XMP metadata of input document if present

             */

            if (p.pcos_get_string(indoc, "type:/Root/Metadata")

                                                    .equals("stream")) {

                xmp = p.pcos_get_stream(indoc, "", "/Root/Metadata");

                p.create_pvf("/xmp/document.xmp", xmp, "");

                optlist += " metadata={filename=/xmp/document.xmp}";

            }


            /*

             * Read Tagged status of input document

             */

            taggedinput = p.pcos_get_string(indoc, "tagged").equals("true");


            if (taggedinput)

                optlist += " tag={tagname=Document}";


            /*

             * Create a new document and clone PDF/A, PDF/UA and PDF/X status

             */

            if (p.begin_document(title + ".pdf", optlist) == -1)

                throw new Exception("Error: " + p.get_apiname() + ": "

                                                        + p.get_errmsg());


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

            p.set_info("Title", title + " $Revision: 1.11 $");


            /*

             * Clone PDF/A or PDF/X output intent

             */

            p.process_pdi(indoc, -1, "action=copyoutputintent");


            /* Create a bookmark with the name of the input document */

            p.create_bookmark(pdfinputfile, "");


            endpage = (int) p.pcos_get_number(indoc, "length:pages");


            /* Copy all pages of the input document */

            for (pageno = 1; pageno <= endpage; pageno++) {

                String lowerleftcorner[][] = {

                    { "x1", "y1" }, /* 0 degrees */

                    { "x2", "y2" }, /* 90 degrees */

                    { "x3", "y3" }, /* 180 degrees */

                    { "x4", "y4" }, /* 270 degrees */

                };


                int page = p.open_pdi_page(indoc, pageno, "cloneboxes");


                if (page == -1) {

                    System.err.println("Error: " + p.get_errmsg());

                    continue;

                }


                /*

                 * Query the geometry of the cloned page. This is required to

                 * account for translated or rotated pages if we want to add

                 * more contents to the page.

                 */

                phi = p.info_pdi_page(page, "rotate", "");


                /*

                 * Select the lower left corner depending on the rotation angle

                 */

                x = p.info_pdi_page(page, lowerleftcorner[(int) (phi / 90)][0],

                    "");

                y = p.info_pdi_page(page, lowerleftcorner[(int) (phi / 90)][1],

                    "");


                boolean fittingpossible = true;

                String additionaltag = "";


                if (taggedinput) {

                    int topleveltagcount = (int) p.info_pdi_page(page,

                        "topleveltagcount", "");


                    if (topleveltagcount == 0) {

                        /*

                         * The page doesn't contain any structure elements, i.e.

                         * it is empty or contains only Artifacts. Some

                         * applications may decide to skip such pages.

                         *

                         * We add an "Artifact" tag to work around an Acrobat

                         * bug.

                         */

                        additionaltag = "tag={tagname=Artifact} ";

                    }

                    else if (p.info_pdi_page(page, "fittingpossible", "")

                                                                        == 0) {

                        /*

                         * Try to place the page without any additional tag; if

                         * this doesn't work we insert another tag.

                         */

                        additionaltag = "tag={tagname=P} ";

                        if (p.info_pdi_page(page, "fittingpossible",

                            additionaltag) == 0) {

                            fittingpossible = false;

                        }

                    }

                }


                if (fittingpossible) {

                    /* Dummy page size; will be adjusted by "cloneboxes" option */

                    p.begin_page_ext(10, 10, "");


                    optlist = "cloneboxes ";

                    if (taggedinput)

                        optlist += additionaltag;


                    p.fit_pdi_page(page, 0, 0, optlist);


                    /*

                     * Adjust the coordinate system to facilitate adding new

                     * page content on top of the cloned page.

                     */

                    p.translate(x, y);

                    p.rotate(phi);


                    width = p.info_pdi_page(page, "pagewidth", "");

                    height = p.info_pdi_page(page, "pageheight", "");


                    /*

                     * Add some text on each page and tag it as Artifact.

                     */

                    optlist = "fontname=DejaVuSerif encoding=unicode embedding "

                        + "textrendering=1 stamp=ll2ur "

                        + "boxsize={" + width + " " + height + "}";


                    if (taggedinput)

                        optlist += " tag={tagname=Artifact}";


                    p.fit_textline("Cloned page", 0, 0, optlist);

                }

                else {

                    System.err.println("Skipping page " + pageno + " of '"

                        + pdfinputfile + "': " + p.get_errmsg());

                }

               

                p.close_pdi_page(page);


                p.end_page_ext("");

            }


            p.end_document("");

            p.delete_pvf("/xmp/document.xmp");

            p.close_pdi_document(indoc);

        }

        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);

        }

    }

}