pCOS Cookbook

cookbook

special/defaultlayers

Emit the indented list of layer names which is presented in Acrobat by default. This will print 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.

Download Java Code     Show Output     Show Input PDF

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;

/**
 * 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 (pCOS 3.x, PDFlib+PDI/PPS 7.x, TET 2.2,
 * PLOP 3.x) <br>
 * Required data: PDF document
 * 
 * @version $Id: defaultlayers.java,v 1.6 2015/11/16 11:53:16 stm Exp $
 */
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 locked_layers = new HashMap();

            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, new Boolean(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 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\n");
    }

    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, String full_rcs_file_name, String revision) {
        super(argv, readable_name, search_path, full_rcs_file_name, revision);
    }

    public static void main(String argv[]) {
        defaultlayers example = new defaultlayers(argv, "Default layer names",
            SEARCH_PATH, "$RCSfile: defaultlayers.java,v $", "$Revision: 1.6 $");
        example.execute();
    }
}