PDFlib

高度なPDFアプリケーションの開発を支援する定番プログラムライブラリー Supported by インフォテック株式会社

PDFlib サンプル集(クックブック)

本サンプルプログラムは、PDF 文書生成ライブラリーの実装である PDFlib の基本的な機能を実際のプログラムで紹介したものです。

本サイトでダウンロードした PDFlib は、一部機能の制限を除き、評価版として無償でお使いいただけます。

イメージクリッピングパスによるテキスト

PDFlib で、TIFF や JPEG イメージからクリッピングパスを使ってテキストを出力するサンプルプログラムです。

  • ケース1:二つのテキストカラムの中央にクリッピングパスによりイメージをフィットします。
  • ケース2:イメージクリッピングパスの内側にテキストをラップします。
  • ケース3:クリッピングパスを使ってこの周りにテキストを置きます。

必要な製品:PDFlib または PDFlib+PDI または PPS


/*
 * 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 10
 * Required data: image file
 */
package com.pdflib.cookbook.pdflib.textflow;

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=NotoSerif-Regular fontsize=10.5 "
                + "fillcolor={gray 0} alignment=justify";

        final String optlist2 = 
            "fontname=NotoSerif-Regular fontsize=10.5 "
                + "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";
        int exitcode = 0;

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

            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(0, 0, "width=a4.width height=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=NotoSerif-Regular fontsize=16 ");
                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.println("PDFlib exception occurred:");
            System.err.println("[" + e.get_errnum() + "] " + e.get_apiname() +
                ": " + e.get_errmsg());
            exitcode = 1;
        }
        catch (Exception e) {
            System.err.println(e);
            exitcode = 1;
        }
        finally {
            if (p != null) {
                p.delete();
            }
            System.exit(exitcode);
        }
    }
}

(Apr 3, 2007 - Jun 20, 2024)