PDFlib Cookbook

cookbook

text_output/text_on_a_path

Create text on a path.

Download Java Code  Switch to PHP Code  Show Output 

/*
 * Create text on a path
 * 
 * Required software: PDFlib/PDFlib+PDI/PPS 9
 * Required data: Image file with clipping path
 */
package com.pdflib.cookbook.pdflib.text_output;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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

public class text_on_a_path {
    
    /**
     * Interface for the different use cases.
     */
    interface use_case {
        void create_page_content(pdflib p) throws PDFlibException, Exception;
        String use_case_description();
    }
    
    /**
     * Execute the example.
     */
    public void run() {
        /* This is where the data files are. Adjust as necessary. */
        final String searchpath = "../input";
        final String outfile = "text_on_a_path.pdf";
        final String imagefile = "luise.jpg";
        final String title = "Text on a Path";
        
        pdflib p = null;
        int exitcode = 0;
        
        /* The page dimensions */
        final double a4_width = 595, a4_height = 842;
        
        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");

            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 font = p.load_font("NotoSerif-Regular", "unicode", "");
            if (font == -1)
                throw new Exception("Error: " + p.get_apiname() + ": "
                        + p.get_errmsg());

            List<use_case> use_cases = new ArrayList<use_case>();
            
            use_cases.add(new use_case() {
                public String use_case_description() {
                    return "Text on Explicitly Constructed Path";
                }

                public void create_page_content(pdflib p)
                        throws PDFlibException {
                    double x = a4_width / 2, y = a4_height / 2;
                    final double radius = 150;
                    
                    /* Draw a circle in the origin; use "clockwise=false"
                     * to place text in the reverse direction.
                     */
                    int path=-1;
                    path = p.add_path_point(path, 0, 0, "circle",
                    		"clockwise=true radius=" + radius);

                    /* Place text on the path */
                    p.setfont(font, 36);

                    /* By default the circle and therefore the text starts at
                     * the "western" side of the circle. We translate to the
                     * origin of the circle and then rotate to start the text
                     * at the top (or some other location on the circle,
                     * e.g. use +90 to start the text at the bottom).
                     */
                    p.save();
	                    p.translate(x, y);
	                    p.rotate(-90);
	                    p.fit_textline(
	                        "Long Distance Glider with sensational range!",
	                        0, 0,
	                        "textpath={path=" + path + "} position={left bottom}");
	
	                    /* We also draw the path for demonstration purposes */
	                    p.draw_path(path, 0, 0, "stroke");
                    p.restore();
                    
                    p.delete_path(path);
                }
            });
            
            use_cases.add(new use_case() {
                public String use_case_description() {
                    return "Text on Clipping Path of Image";
                }

                public void create_page_content(pdflib p)
                        throws PDFlibException, Exception {
                    /*
                     * Load image and retrieve its clipping path.
                     */
                    final int image = p.load_image("auto", imagefile, "");
                    if (image == -1)
                        throw new Exception("Error: " + p.get_apiname() + ": "
                                + p.get_errmsg());

                    final int image_clipping_path = 
                                (int) p.info_image(image, "clippingpath", "");
                    if (image_clipping_path == -1)
                        throw new Exception(
                            "Error: Image does not contain a clipping path");
                    
                    /*
                     * Center the image on the page, scale it to half the size
                     * of the page.
                     */
                    double img_width = a4_height / 2, 
                            img_height = a4_width / 2;
                    double box_llx = a4_width / 2 - img_width / 2, 
                            box_lly = a4_height / 2 - img_height / 2;
                    
                    final String fit_options = "boxsize={" + img_width + " "
                            + img_height + "} position=center fitmethod=meet";
                    p.fit_image(image, box_llx, box_lly, fit_options);
                    
                    final double image_llx = box_llx
                        + p.info_image(image, "x1", fit_options);
                    final double image_lly = box_lly
                        + p.info_image(image, "y1", fit_options);
            
                    /*
                     * Determine the scaling factors for the image.
                     */
                    final double img_scale_factor_x = 
                        p.info_image(image, "fitscalex", fit_options);
                    final double img_scale_factor_y = 
                        p.info_image(image, "fitscaley", fit_options);
                    final String scale_option = "scale={" + img_scale_factor_x
                        + " " + img_scale_factor_y + "}";
                    
                    /* Place text on the path; we start at 23% of the
                     * path length for a nice effect.
                     */
                    p.setfont(font, 24);
                    p.fit_textline(
                        "Hi! I'm Louise!",
                        image_llx, image_lly,
                        "textpath={path=" + image_clipping_path + " " 
                        + scale_option + "} position={23 bottom} " +
                        "matchbox={boxheight={capheight descender}}");
                    
                    p.delete_path(image_clipping_path);
                    p.close_image(image);
                }
            });

            use_cases.add(new use_case() {
                public String use_case_description() {
                    return "Create a Gap Between Text and Path";
                }

                public void create_page_content(pdflib p)
                        throws PDFlibException {
                    /*
                     * Create a path defined by Bezier curves. The path extends
                     * through a box that is half the size of the page. The box
                     * is centered on the page.
                     */
                    final double box_center_x = a4_width / 2,
                            box_center_y = a4_height / 2;
                    final double box_width = box_center_y, 
                            box_height = box_center_x;
                    final double box_llx = box_center_x - box_width / 2, 
                            box_lly = box_center_y - box_height / 2;
                    
                    /*
                     * The path is defined through the implicit point at (0, 0)
                     * and six additional control points
                     */
                    final double step = box_width / 6;
                    int path = p.add_path_point(-1, step * 1, 
                                box_height / 2, "control", "");
                    path = p.add_path_point(path, step * 2, 
                                box_height / 2, "control", "");
                    path = p.add_path_point(path, step * 3, 
                                box_height / 2, "curve", "");
                    path = p.add_path_point(path, step * 4, 
                                box_height / 2, "control", "");
                    path = p.add_path_point(path, step * 5, 
                                box_height / 2, "control", "");
                    path = p.add_path_point(path, step * 6, 
                                box_height, "curve", "");
                    
                    /* Place text on the path */
                    p.setfont(font, 24);
                    p.fit_textline(
                        "Long Distance Glider with sensational range!",
                        box_llx, box_lly,
                        "textpath={path=" + path + "} position={center bottom} "
                        + "matchbox={boxheight={capheight descender}}");
                    
                    /* We also draw the path for demonstration purposes */
                    p.draw_path(path, box_llx, box_lly, "stroke");
                    
                    p.delete_path(path);
                }
            });
            
            use_cases.add(new use_case() {
                public String use_case_description() {
                    return "Place Text on Right Side of Path";
                }

                public void create_page_content(pdflib p)
                        throws PDFlibException {
                    /*
                     * Create a path defined by Bezier curves. The path extends
                     * through a box that is half the size of the page. The box
                     * is centered on the page.
                     */
                    final double box_center_x = a4_width / 2,
                            box_center_y = a4_height / 2;
                    final double box_width = box_center_y, 
                            box_height = box_center_x;
                    final double box_llx = box_center_x - box_width / 2, 
                            box_lly = box_center_y - box_height / 2;
                    
                    /*
                     * The path this time starts at the upper left corner of the
                     * box.
                     */
                    final double step = box_width / 6;
                    int path = p.add_path_point(-1, step * 0, box_height, 
                                                "move", "");
                    path = p.add_path_point(path, step * 1, box_height / 2, 
                                                "control", "");
                    path = p.add_path_point(path, step * 2, box_height / 2, 
                                                "control", "");
                    path = p.add_path_point(path, step * 3, box_height / 2, 
                                                "curve", "");
                    path = p.add_path_point(path, step * 4, box_height / 2, 
                                                "control", "");
                    path = p.add_path_point(path, step * 5, box_height / 2, 
                                                "control", "");
                    path = p.add_path_point(path, step * 6, 0, "curve", "");
                    
                    /* Place text on the path */
                    p.setfont(font, 24);
                    p.fit_textline(
                        "Long Distance Glider with sensational range!",
                        box_llx, box_lly,
                        "textpath={path=" + path + "} position={center top}");
                    
                    /* We also draw the path for demonstration purposes */
                    p.draw_path(path, box_llx, box_lly, "stroke");
                    
                    p.delete_path(path);
                }
            });
            
            /*
             * Place the use cases.
             */
            final double headline_x = a4_width / 2, 
                            headline_y = a4_height * 4 / 5;
            
            Iterator<use_case> use_case_iterator = use_cases.iterator();
            while (use_case_iterator.hasNext()) {
                use_case c = use_case_iterator.next();
                
                p.begin_page_ext(0, 0, "width=a4.width height=a4.height");

                /*
                 * Options for the per-example header line
                 */
                final String optlist = "position=center";
                p.setfont(font, 30);
                p.fit_textline(c.use_case_description(), headline_x, headline_y,
                                optlist);
                
                c.create_page_content(p);

                p.end_page_ext("");
            }
            
            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);
        }
    }
    
    public static void main(String[] args) {
        new text_on_a_path().run();
    }
}