BASKET
Search
PDFlib

text_output/text_with_image_clipping_path

Download Java Code      Switch to PHP Code     Show Output PDF

/* $Id: text_with_image_clipping_path.java,v 1.12 2013/02/26 11:10:24 stm Exp $

 *

 * Text and image clipping paths:

 * Use the clipping path from a TIFF or JPEG image to shape text output.

 *

 * Case 1:

 *      Fit image with clipping path into the center of two text columns

 *

 * Case 2:

 *      Wrap text inside an image clipping path.

 *     

 * Case 3:

 *      Use clipping path to flow text around it

 *

 * Required software: PDFlib/PDFlib+PDI/PPS 9

 * Required data: image file

 */

package com.pdflib.cookbook.pdflib.text_output;


import java.util.ArrayList;

import java.util.List;


import com.pdflib.pdflib;

import com.pdflib.PDFlibException;


public class text_with_image_clipping_path {

    /**

     * Create some amount of dummy text and feed it to a Textflow object with

     * alternating options.

     */

    static int create_textflow(pdflib p) throws PDFlibException, Exception {

        /* Repeat the dummy text to produce more contents */

        final int count = 20;

        final String optlist1 =

            "fontname=DejaVuSerif fontsize=10.5 encoding=unicode "

                + "fillcolor={gray 0} alignment=justify";


        final String optlist2 =

            "fontname=DejaVuSerif fontsize=10.5 encoding=unicode "

                + "fillcolor={rgb 1 0 0} charref";


        /*

         * Dummy text for filling the columns. Soft hyphens are marked with the

         * character reference "­" (character references are enabled by the

         * charref option).

         */

        final String text =

            "Lorem ipsum dolor sit amet, consectetur adi­pi­sicing elit, "

            + "sed do eius­mod tempor incidi­dunt ut labore et dolore "

            + "magna ali­qua. Ut enim ad minim ve­niam, quis nostrud "

            + "exer­citation ull­amco la­bo­ris nisi ut "

            + "ali­quip ex ea commodo con­sequat. Duis aute irure dolor "

            + "in repre­henderit in voluptate velit esse cillum dolore eu "

            + "fugiat nulla pari­atur. Excep­teur sint occae­cat "

            + "cupi­datat non proident, sunt in culpa qui officia "

            + "dese­runt mollit anim id est laborum. ";


        int tf = -1;

        for (int i = 1; i <= count; i++) {

            String num = i + " ";


            tf = p.add_textflow(tf, num, optlist2);

            if (tf == -1)

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

                        + p.get_errmsg());


            tf = p.add_textflow(tf, text, optlist1);

            if (tf == -1)

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

                        + p.get_errmsg());

        }


        return tf;

    }


    /**

     * Interface for the different use cases.

     */

    interface use_case {

        void create_page_contents(pdflib p, int tf) throws PDFlibException;


        String use_case_description();

    }


    public static void main(String argv[]) {

        pdflib p = null;


        final String outfile = "text_with_image_clipping_path.pdf";

        final String title = "Text With Image Clipping Path";

        final String imagefile = "child_clipped.jpg";

        final String searchpath = "../input";


        try {

            p = new pdflib();


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

            p.set_option("errorpolicy=return");


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


            if (p.begin_document(outfile, "") == -1)

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

                        + p.get_errmsg());


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

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


            final int image = p.load_image("auto", imagefile, "");

            if (image == -1)

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

                        + p.get_errmsg());


            final int path = (int) p.info_image(image, "clippingpath", "");

            if (path == -1)

                throw new Exception(

                        "Error: The image does not contain a clipping path");


            /*

             * Coordinates for laying out the text and the image.

             */


            /* The page dimensions */

            final double a4_width = 595, a4_height = 842;


            /* The margin at the left- and right-hand sides of the page */

            final double margin = 50;


            /* The distance between the two columns */

            final double column_distance = margin / 2;


            /* Positions and sizes of the columns */

            final double column_width =

                (a4_width - (2 * margin) - column_distance) / 2;

            final double column_height = a4_height / 3;


            final double llx1 = margin, lly1 = a4_height / 3;

            final double urx1 = llx1 + column_width, ury1 = lly1

                    + column_height;


            final double llx2 = margin + column_width + column_distance,

                    lly2 = lly1;

            final double urx2 = llx2 + column_width, ury2 = ury1;


            /* Size of the box that covers the two columns */

            final double bbox_width = urx2 - llx1, bbox_height = ury2 - lly1;


            /*

             * The image will be centered into a box that covers a quarter of

             * the text box.

             */

            final double image_width = bbox_width / 2,

                    image_height = bbox_height / 2;

            final String with_clipping_opts = "boxsize={" + image_width + " "

                    + image_height + "} " + "position=center fitmethod=meet";

            final String no_clipping_opts = with_clipping_opts

                    + " ignoreclippingpath";


            /*

             * The position for displaying the title for the use case.

             */

            final double title_llx = llx1, title_lly = ury1;

            final double title_urx = title_llx + bbox_width,

                        title_ury = title_lly + 100;

            /*

             * Box position for placing the image

             */

            final double image_llx = llx1 + (bbox_width / 4);

            final double image_lly = lly1 + (bbox_height / 4);


            /*

             * Determine reference point for the image after it was placed into

             * the center of the bounding box of the two columns.

             */

            final double placed_image_llx = image_llx

                    + p.info_image(image, "x1", with_clipping_opts);

            final double placed_image_lly = image_lly

                    + p.info_image(image, "y1", with_clipping_opts);


            /*

             * Determine the scaling factor for the image. "fitmethod=meet"

             * scales uniformly in x and y direction, so it is sufficient to

             * fetch one scaling factor.

             */

            final double image_scale_factor = p.info_image(image, "fitscalex",

                    with_clipping_opts);

            final String scale_option = "scale=" + image_scale_factor;


            List<use_case> use_cases = new ArrayList<use_case>();


            /*

             * Use case 1:

             *

             * Fit the image with clipping into the center of the text box. Fit

             * the text into the text box, and wrap it around the path retrieved

             * from the image. The path must be scaled in the same manner as the

             * image was scaled.

             */

            use_cases.add(new use_case() {

                public String use_case_description() {

                    return "Fit image with clipping path into the center "

                            + "of two text columns";

                }


                public void create_page_contents(pdflib p, int tf)

                        throws PDFlibException {

                    p.fit_image(image, image_llx, image_lly,

                                    with_clipping_opts);


                    final String textflow_opts = "wrap={offset=5 paths={{path="

                            + path + " refpoint={" + placed_image_llx + " "

                            + placed_image_lly + "} " + scale_option + "}}}";


                    /* Fill the first column */

                    final String result = p.fit_textflow(tf, llx1, lly1, urx1,

                            ury1, textflow_opts);


                    /* Fill the second column if we have more text */

                    if (!result.equals("_stop"))

                        p.fit_textflow(tf, llx2, lly2, urx2, ury2,

                                textflow_opts);

                }

            });


            /*

             * Use case 2:

             *

             * Use the inversefill option to wrap text inside the path instead

             * of wrapping the text around the path (i.e. the path serves as

             * text container instead of creating a hole in the Textflow). For

             * creating a "hole" in the image, the image is placed without

             * honoring the clipping path, and the clipping path is used to draw

             * a white area inside the image

             */

            use_cases.add(new use_case() {

                public String use_case_description() {

                    return "Wrap text inside the clipping path of an image";

                }


                public void create_page_contents(pdflib p, int tf)

                        throws PDFlibException {

                    p.fit_image(image, image_llx, image_lly, no_clipping_opts);


                    p.draw_path(path, placed_image_llx, placed_image_lly,

                            "fill=true fillcolor=white " + scale_option);


                    p.fit_textflow(tf, llx1, lly1, urx2, ury2,

                            "wrap={offset=5 inversefill paths={{path=" + path

                                    + " refpoint={" + placed_image_llx + " "

                                    + placed_image_lly + "} " + scale_option

                                    + "}}}");

                }

            });


            /*

             * Use case 3:

             *

             * Do not place the image, but use its clipping path to flow text

             * around it. The reference point for the clipping path is specified

             * relatively to the fitbox of the textflow by percentages of the

             * width and height of the fitbox in the "refpoint" suboption.

             */

            use_cases.add(new use_case() {

                public String use_case_description() {

                    return "Use clipping path to flow text around it";

                }


                public void create_page_contents(pdflib p, int tf)

                        throws PDFlibException {

                    p.fit_textflow(tf, llx1, lly1, urx2, ury2,

                            "wrap={offset=5 paths={{path=" + path

                                    + " refpoint={25% 25%} " + scale_option

                                    + "}}}");

                }

            });


            /*

             * Create one page for each use case.

             */

            for (int i = 0; i < use_cases.size(); i += 1) {

                final use_case c = use_cases.get(i);


                p.begin_page_ext(a4_width, a4_height, "");


                /*

                 * Add a description for each use case.

                 */

                final String desc = "Use case " + (i + 1) + ": "

                        + c.use_case_description();

                final int title_tf = p.create_textflow(desc,

                        "fontname=DejaVuSerif fontsize=16 encoding=unicode");

                p.fit_textflow(title_tf, title_llx, title_lly, title_urx,

                        title_ury, "");

                p.delete_textflow(title_tf);


                /*

                 * Create a textflow and pass that to the create_page_contents()

                 * method to put the contents on the page.

                 */

                final int tf = create_textflow(p);

                c.create_page_contents(p, tf);

                p.delete_textflow(tf);


                p.end_page_ext("");

            }


            p.delete_path(path);

            p.close_image(image);


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

            }

        }

    }

}