PDFlib Cookbook

cookbook

path_objects/arrow_as_path_object

Example for a path object: arrow with rounded arrow head and two attachment points.

Download Java Code  Switch to PHP Code  Show Output 

/*
 * Arrows: Create arrows using path objects
 *
 * Required software: PDFlib/PDFlib+PDI/PPS 9
 * Required data: none
 */
package com.pdflib.cookbook.pdflib.path_objects;

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

public class arrow_as_path_object {
    /**
     * Describe an add_path_point operation
     */
    static class point {
        point(double x, double y, String type, String optlist) {
            this.x = x;
            this.y = y;
            this.type = type;
            this.optlist = optlist;
        }
        double x;
        double y;
        String type;
        String optlist;
    };
    
    /**
     * Describe a path with the draw operation
     */
    static class path {
        path(point ops[], String optlist) {
            this.ops = ops;
            this.draw_path_optlist = optlist;
        }
        
        point ops[];            /* Array of points */
        String draw_path_optlist;         /* Option list for draw_path() */
    };
    
    static path paths[] = {
        /* black arrow with rounded corners */
        new path(new point[] {
            new point(-25.0, 0.0, "move", "round=10"),
            new point(-75.0, 0.0, "line", ""),
            new point(0.0, 100.0, "line", ""),
            new point(75.0, 0.0, "line", ""),
            new point(25.0, 0.0, "line", ""),
            new point(25.0, -200.0, "line", ""),
            new point(0.0, -200.0, "line", ""),
            new point(-25.0, -200.0, "line", ""),
        },
        "fill close"),

        /* white arrow in blue circle */
        new path(new point[] {
            new point(0, 200.0, "move", "fillcolor=blue"),
            new point(0, -200.0, "control", ""),
            new point(0, 200.0, "circular", ""),
            new point(-25.0, 50.0, "move", "fillcolor=white"),
            new point(-75.0, 50.0, "line", ""),
            new point(0.0, 150.0, "line", ""),
            new point(75.0, 50.0, "line", ""),
            new point(25.0, 50.0, "line", ""),
            new point(25.0, -150.0, "line", ""),
            new point(0.0, -150.0, "line", ""),
            new point(-25.0, -150.0, "line", ""),
            new point(-25.0, 50.0, "line", ""),
        },
        "fill"),
        
        /* black arrow in white circle with black border */
        new path(new point[] {
            new point(0, 210.0, "move", "fillcolor=black"),
            new point(0, -210.0, "control", ""),
            new point(0, 210.0, "circular", ""),
            new point(0, 200.0, "move", "fillcolor=white"),
            new point(0, -200.0, "control", ""),
            new point(0, 200.0, "circular", ""),
            new point(-50.0, 0, "move", "fillcolor=black"),
            new point(-150.0, 0, "line", ""),
            new point(0.0, 150.0, "line", ""),
            new point(150.0, 0, "line", ""),
            new point(50.0, 0, "line", ""),
            new point(50.0, -150.0, "line", ""),
            new point(0.0, -150.0, "line", ""),
            new point(-50.0, -150.0, "line", ""),
            new point(-50.0, 50.0, "line", ""),
        },
        "fill"),
        
        /* black triangle inside grey square with black rounded border */
        new path(new point[] {
            new point(-48.0, -48.0, "move", "round=20 fillcolor=black"),
            new point(-48.0,  48.0, "line", ""),
            new point( 48.0,  48.0, "line", ""),
            new point( 48.0, -48.0, "line", ""),

            new point(-42.0, -42.0, "move", "round=16 fillcolor=silver"),
            new point(-42.0,  42.0, "line", ""),
            new point( 42.0,  42.0, "line", ""),
            new point( 42.0, -42.0, "line", ""),

            new point(-22.0, -27.0, "move", "fillcolor=black"),
            new point(-22.0,  27.0, "line", ""),
            new point( 24.765, 0.0, "line", ""),
            new point(-22.0, -27.0, "line", ""),
        },
        "fill close")
    };
    
    final static double PG_WIDTH = 500;
    final static double PG_HEIGHT = 500;
    final static int ROTATION_STEPS = 4;
    final static double ROTATION_LIMIT = 360;
    final static double ROTATION_STEPS_DEG = ROTATION_LIMIT / ROTATION_STEPS;
    
    /* Dimensions for the box for a single arrow variation */
    final static double BOX_WIDTH = PG_WIDTH / ROTATION_STEPS;
    final static double BOX_HEIGHT = BOX_WIDTH;
    
    /* Leave some space around the individual arrows */
    final static double BOX_MARGIN = 0.1;
    final static double INNER_BOX_WIDTH = (1 - (2 * BOX_MARGIN)) * BOX_WIDTH;
    final static double INNER_BOX_HEIGHT = (1 - (2 * BOX_MARGIN)) * BOX_HEIGHT;
    
    /* Distribute the variations evenly across the page */
    final static double Y_DISPLACEMENT = 
        (PG_HEIGHT - (paths.length * BOX_HEIGHT)) / (paths.length + 1);
    
    public static void main(String argv[]) {
        /* This is where the data files are. Adjust if necessary. */
        String searchpath = "../input";
        String outfile = "arrow_as_path_object.pdf";
        String title = "Arrows as path objects";
        int exitcode = 0;

        pdflib p = null;

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

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

            p.begin_page_ext(PG_WIDTH, PG_HEIGHT, "");

            for (int i = 0; i < paths.length; i += 1) {
                draw_path(p, i, paths[i]);
            }

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

    /**
     * Draw a path on the page in ROTATION_STEPS rotated variations.
     * 
     * @param p
     *            The pdflib object
     * @path_number The number of the path, used to position the path vertically
     * @param current_path
     *            The path object to draw
     * 
     * @throws PDFlibException
     */
    private static void draw_path(pdflib p, int path_number, path current_path)
        throws PDFlibException {
        int path = -1;
        int i;
        
        /* Construct path according to path operations */
        for (i = 0; i < current_path.ops.length; i += 1) {
            point pt = current_path.ops[i];
            path = p.add_path_point(path,
                pt.x, pt.y, pt.type, pt.optlist);
        }
        
        /* Draw the rotated variations of the path */
        final double ypos =  (path_number + 1) * Y_DISPLACEMENT 
                            + (path_number + BOX_MARGIN) * BOX_HEIGHT;
        
        for (i = 0; i < ROTATION_STEPS; i += 1) {
            final double rotation = i * ROTATION_STEPS_DEG;
            final double xpos = i * BOX_WIDTH + BOX_MARGIN * BOX_WIDTH;
            
            /* Draw path */
            final String placement_opts = 
                " boxsize={" + INNER_BOX_WIDTH + " " + INNER_BOX_HEIGHT 
                    + "} orientate=" + rotation
                    + " fitmethod=meet position=center";
            p.draw_path(path, xpos, ypos,
                        current_path.draw_path_optlist + placement_opts);
        }
        
        p.delete_path(path);
    }
}