pCOS Cookbook

cookbook

special/defaultlayers

Emit the indented list of layer names which is presented in Acrobat by default.

Download Java Code  Show Output  Show Input (layernames.pdf) 

/*
 * Emit the indented list of layer names which is presented in Acrobat by
 * default.
 * <p>
 * This Cookbook topic prints the layer information in the same manner as
 * Acrobat displays the layers in a hierarchical way. Note that this
 * presentation may miss layers which are actually contained in the document
 * e.g. layers which are not controlled interactively, but via JavaScript. For
 * getting a full list of all the layers in a document in a non-hierarchical
 * presentation use the "layers" Cookbook topic.
 * <p>
 * Required software: pCOS interface 3 (PDFlib+PDI/PPS 7.x, TET 2.2,
 * PLOP 3.x) <br>
 * Required data: PDF document
 */

package com.pdflib.cookbook.pcos.special;

import java.util.HashMap;
import java.util.Map;

import com.pdflib.IpCOS;
import com.pdflib.cookbook.pcos.pcos_cookbook_example;

public class defaultlayers extends pcos_cookbook_example {

    /* This is where the data files are. Adjust as necessary. */
    private final static String SEARCH_PATH = "../input";

    private final static String KEY = "/Root/OCProperties";

    public void example_code(IpCOS p, int doc) throws Exception {

        System.out.println("File name: " + p.pcos_get_string(doc, "filename"));

        String objtype = p.pcos_get_string(doc, "type:" + KEY);
        if (!objtype.equals("dict")) {
            System.out.println("No layers found\n");
            return;
        }

        /* Use the /Order array */
        objtype = p.pcos_get_string(doc, "type:" + KEY + "/D/Order");
        if (objtype.equals("array")) {
            /*
             * Prepare a Map of all locked layers because this information is
             * global for the "D" dictionary
             */
            Map<String, Boolean> locked_layers = new HashMap<String, Boolean>();

            int locked_layers_count = (int) p.pcos_get_number(doc, "length:"
                + KEY + "/D/Locked");
            for (int i = 0; i < locked_layers_count; i += 1) {
                String locked_layer_name = p.pcos_get_string(doc, KEY
                    + "/D/Locked[" + i + "]/Name");
                locked_layers.put(locked_layer_name, Boolean.valueOf(true));
            }

            /* Recursively check all entries */
            check_ocg_entry(p, doc, 0, KEY + "/D/Order", locked_layers);
        }
        else {
            System.out
                .println("No recommended order for presentation of layers available.");
        }
    }

    private void check_ocg_entry(IpCOS p, int doc, int level, String base,
        Map<String, Boolean> locked_layers) throws Exception {
        String objtype = p.pcos_get_string(doc, "type:" + base);

        /*
         * If it's an array it indicates a nested set of layers. Indent and
         * process all subordinate OCGs.
         */
        if (objtype.equals("array")) {
            int numentries = (int) p.pcos_get_number(doc, "length:" + base);
            int i = 0;

            level++;

            /* The first element can be a string which holds a label name. */
            objtype = p.pcos_get_string(doc, "type:" + base + "[0]");

            if (objtype.equals("string")) {
                String indentation = getIndentationString(level);

                System.out.println(indentation + "["
                    + p.pcos_get_string(doc, base + "[0]") + "]");

                i = 1;
            }

            for (/* */; i < numentries; i++) {
                String path = base + "[" + i + "]";
                check_ocg_entry(p, doc, level, path, locked_layers);
            }
        }
        /* If it's a dict: print the layer Name */
        else if (objtype.equals("dict")) {
            String indentation = getIndentationString(level);
            String layer_name = p.pcos_get_string(doc, base + "/Name");
            System.out.print(indentation + layer_name);

            if (locked_layers.containsKey(layer_name)) {
                System.out.print(" (locked)");
            }

            System.out.println();
        }
        else
            System.out.println("PDF error in OCG Order array.");
    }

    private String getIndentationString(int level) {
        int indentation = level * 4;
        StringBuffer s = new StringBuffer(indentation);
        for (int i = 0; i < indentation; i += 1) {
            s.append(' ');
        }
        return s.toString();
    }

    public defaultlayers(String[] argv, String readable_name,
        String search_path) {
        super(argv, readable_name, search_path);
    }

    public static void main(String argv[]) {
        defaultlayers example = new defaultlayers(argv, "Default layer names",
            SEARCH_PATH);
        example.execute();
    }
}