All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.objects.layers.PdfLayerList Maven / Gradle / Ivy

/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/support/
 *
 * (C) Copyright 1997-2017 IDRsolutions and Contributors.
 *
 * This file is part of JPedal/JPDF2HTML5
 *
 @LICENSE@
 *
 * ---------------
 * PdfLayerList.java
 * ---------------
 */
package org.jpedal.objects.layers;

import java.util.*;

import org.jpedal.io.PdfFileReader;
import org.jpedal.io.PdfObjectFactory;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.raw.OCObject;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfKeyPairsIterator;
import org.jpedal.objects.raw.PdfObject;

public class PdfLayerList {

    private static boolean debug;

    /**
     * page we have outlines for
     */
    private int OCpageNumber = -1;

    private String padding = "";

    //used in tree as unique separator
    public static final char deliminator = (char) 65535;

    private final Map layerNames = new LinkedHashMap();

    private final Map streamToName = new HashMap();

    private final Map layersEnabled = new HashMap();

    private Map jsCommands;

    private final Map metaData = new HashMap();

    private final Map layersTested = new HashMap();

    private final Map layerLocks = new HashMap();

    private boolean changesMade;

    private Map propertyMap;
    private Map refToPropertyID;
    private Map refTolayerName;
    private Map RBconstraints;

    private final Map minScale = new HashMap();
    private final Map maxScale = new HashMap();

    //private float scaling=1f;

    private int layerCount;
    private Object[] order;

    private PdfObjectReader currentPdfFile;

    private Layer[] layers;


    /**
     * add layers and settings to list
     *
     * @param OCProperties   is of type PdfObject
     * @param PropertiesObj  is of type PdfObject
     * @param currentPdfFile is of type PdfObjectReader
     * @param pageNumber     is of type int
     */
    public void init(final PdfObject OCProperties, final PdfObject PropertiesObj, final PdfObjectReader currentPdfFile, final int pageNumber) {

        OCpageNumber = pageNumber;

        propertyMap = new HashMap();
        refToPropertyID = new HashMap();
        refTolayerName = new HashMap();
        RBconstraints = new HashMap();

        this.currentPdfFile = currentPdfFile;

        if (PropertiesObj != null) {
            setupOCMaps(PropertiesObj, currentPdfFile);
        }

        final PdfObject layerDict = OCProperties.getDictionary(PdfDictionary.D);

        if (layerDict == null) {
            return;
        }

        int OCBaseState = layerDict.getNameAsConstant(PdfDictionary.BaseState);

        //if not set use default
        if (OCBaseState == PdfDictionary.Unknown) {
            OCBaseState = PdfDictionary.ON;
        }

        //read order first and may be over-written by ON/OFF
        order = layerDict.getObjectArray(PdfDictionary.Order);

        if (debug) {
            System.out.println("PropertiesObj=" + PropertiesObj);
            System.out.println("layerDict=" + layerDict);
            System.out.println("propertyMap=" + propertyMap);
            System.out.println("propertyMap=" + propertyMap);
            System.out.println("refToPropertyID=" + refToPropertyID);
            System.out.println("refTolayerName=" + refTolayerName);

            System.out.println("OCBaseState=" + OCBaseState + " (ON=" + PdfDictionary.ON + ')');


            System.out.println("order=" + Arrays.toString(order));

            showValues("ON=", PdfDictionary.ON, layerDict);

            showValues("OFF=", PdfDictionary.OFF, layerDict);

            showValues("RBGroups=", PdfDictionary.RBGroups, layerDict);

        }
        /*
         * workout list of layers (can be in several places)
         */

        addLayer(OCBaseState, order, null);

        //read the ON and OFF values
        if (OCBaseState != PdfDictionary.ON) //redundant if basestate on
        {
            addLayer(PdfDictionary.ON, layerDict.getKeyArray(PdfDictionary.ON), null);
        }

        if (OCBaseState != PdfDictionary.OFF) //redundant if basestate off
        {
            addLayer(PdfDictionary.OFF, layerDict.getKeyArray(PdfDictionary.OFF), null);
        }

        /*
         * handle case where layers not explicitly switched on
         */
        if (OCBaseState == PdfDictionary.ON) { // && layerDict.getKeyArray(PdfDictionary.OFF)==null){
            final Iterator keys = refToPropertyID.keySet().iterator();
            String ref;
            String layerName;
            while (keys.hasNext()) {
                ref = keys.next();
                layerName = refToPropertyID.get(ref);

                refTolayerName.put(ref, layerName);

                if (!layersTested.containsKey(layerName)) {
                    layersTested.put(layerName, "x");
                    layersEnabled.put(layerName, "x");
                }
            }
        }

        //set any locks
        setLocks(currentPdfFile, layerDict.getKeyArray(PdfDictionary.Locked));

        //any constraints
        setConstraints(layerDict.getKeyArray(PdfDictionary.RBGroups));

        //any Additional Dictionaries
        setAS(layerDict.getKeyArray(PdfDictionary.AS), currentPdfFile);


        /*
         * read any metadata
         */
        final int[] keys = {PdfDictionary.Name, PdfDictionary.Creator};
        final String[] titles = {"Name", "Creator"};

        final int count = keys.length;
        String val;
        for (int jj = 0; jj < count; jj++) {
            val = layerDict.getTextStreamValue(keys[jj]);
            if (val != null) {
                metaData.put(titles[jj], val);
            }
        }

        //list mode if set
        val = layerDict.getName(PdfDictionary.ListMode);
        if (val != null) {
            metaData.put("ListMode", val);
        }

    }

    private static void showValues(final String s, final int key, final PdfObject layerDict) {

        final byte[][] keyValues = layerDict.getKeyArray(key);
        if (keyValues != null) {

            final StringBuilder values = new StringBuilder(s);
            for (final byte[] keyValue : keyValues) {
                if (keyValue == null) {
                    values.append("null ");
                } else {
                    values.append(new String(keyValue)).append(' ');
                }
            }

            System.out.println(values);

        }
    }

    /**
     * used by Javascript to flag that state has changed
     *
     * @param flag is of type boolean
     */
    public void setChangesMade(final boolean flag) {
        changesMade = flag;
    }

    /**
     * build a list of constraints using layer names so
     * we can switch off if needed
     *
     * @param layer
     */
    private void setConstraints(final byte[][] layer) {

        if (layer == null) {
            return;
        }

        final int layerCount = layer.length;

        //turn into list of names
        final String[] layers = new String[layerCount];
        for (int ii = 0; ii < layerCount; ii++) {

            final String ref = new String(layer[ii]);
            layers[ii] = this.refTolayerName.get(ref);
        }

        for (int ii = 0; ii < layerCount; ii++) {

            if (isLayerName(layers[ii])) {

                final StringBuilder effectedLayers = new StringBuilder();
                for (int ii2 = 0; ii2 < layerCount; ii2++) {

                    if (ii == ii2) {
                        continue;
                    }


                    effectedLayers.append(layers[ii2]).append(',');
                }

                RBconstraints.put(layers[ii], effectedLayers.toString());


            }
        }
    }

    /**
     * create list for lookup
     */
    private void setupOCMaps(final PdfObject propertiesObj, final PdfObjectReader currentPdfFile) {

        final PdfKeyPairsIterator keyPairs = propertiesObj.getKeyPairsIterator();

        String glyphKey, ref;
        PdfObject glyphObj;

        final PdfFileReader pdfFileReader = currentPdfFile.getObjectReader();

        while (keyPairs.hasMorePairs()) {

            glyphKey = keyPairs.getNextKeyAsString();

            glyphObj = PdfObjectFactory.getPDFObjectObjectFromRefOrDirect(new OCObject(propertiesObj.getObjectRefAsString()), pdfFileReader, keyPairs.getNextValueAsBytes(), PdfDictionary.OCProperties);

            ref = glyphObj.getObjectRefAsString();

            currentPdfFile.checkResolved(glyphObj);

            final byte[][] childPairs = glyphObj.getKeyArray(PdfDictionary.OCGs);

            if (childPairs != null) {
                setupchildOCMaps(childPairs, glyphKey, currentPdfFile);
            } else {
                propertyMap.put(ref, glyphObj);

                final String currentNames = refToPropertyID.get(ref);
                if (currentNames == null) {
                    refToPropertyID.put(ref, glyphKey);
                } else {
                    refToPropertyID.put(ref, currentNames + ',' + glyphKey);
                }
            }
            //roll on
            keyPairs.nextPair();
        }

    }

    private void setupchildOCMaps(final byte[][] keys, final String glyphKey, final PdfObjectReader currentPdfFile) {

        String ref;
        PdfObject glyphObj;

        for (final byte[] key : keys) {

            ref = new String(key);
            glyphObj = new OCObject(ref);

            currentPdfFile.readObject(glyphObj);

            currentPdfFile.checkResolved(glyphObj);

            final byte[][] childPairs = glyphObj.getKeyArray(PdfDictionary.OCGs);

//System.out.println(glyphKey+" === "+glyphObj+" childPropertiesObj="+childPairs);

            if (childPairs != null) {
                setupchildOCMaps(childPairs, glyphKey, currentPdfFile);
            } else {

                propertyMap.put(ref, glyphObj);
                final String currentNames = refToPropertyID.get(ref);
                if (currentNames == null) {
                    refToPropertyID.put(ref, glyphKey);
                } else {
                    refToPropertyID.put(ref, currentNames + ',' + glyphKey);
                }
                //System.out.println("Add key "+glyphKey+" "+refToPropertyID);
            }
        }
    }

    private void addLayer(final int status, final Object[] layer, String parentName) {

        if (layer == null) {
            return;
        }

        if (debug) {
            padding += "   ";
        }

        final int layers = layer.length;

        String ref, name, layerName = null;

        PdfObject nextObject;

        for (int ii = 0; ii < layers; ii++) {

            if (layer[ii] instanceof String) {
                //ignore
            } else if (layer[ii] instanceof byte[]) {

                final byte[] rawRef = (byte[]) layer[ii];
                ref = new String(rawRef);
                name = refToPropertyID.get(ref);

                nextObject = propertyMap.get(ref);

                if (nextObject == null) {

                    if (rawRef != null && rawRef.length > 1 && rawRef[rawRef.length - 1] == 'R') {
                        nextObject = new OCObject(ref);
                        currentPdfFile.readObject(nextObject);
                        name = ref;
                    } else { //it is a name for the level so add into path of name

                        if (parentName == null) {
                            parentName = ref;
                        } else {
                            parentName = ref + deliminator + parentName;
                        }
                    }
                }

                if (nextObject != null) {

                    layerCount++;

                    layerName = nextObject.getTextStreamValue(PdfDictionary.Name);

                    if (parentName != null) {
                        layerName = layerName + deliminator + parentName;
                    }

                    if (debug) {
                        System.out.println(padding + "[layer1] add layer=" + layerName + " ref=" + ref + " parent=" + parentName + " refToLayerName=" + refTolayerName.get(ref) + " ref=" + ref);
                    }

                    refTolayerName.put(ref, layerName);

                    //and write back name value
                    layer[ii] = layerName;

                    layerNames.put(layerName, status);
                    if (name.indexOf(',') == -1) {
                        final String oldValue = streamToName.get(name);
                        if (oldValue == null) {
                            streamToName.put(name, layerName);
                        } else {
                            streamToName.put(name, oldValue + ',' + layerName);
                        }
                    } else {
                        final StringTokenizer names = new StringTokenizer(name, ",");
                        while (names.hasMoreTokens()) {
                            name = names.nextToken();
                            final String oldValue = streamToName.get(name);
                            if (oldValue == null) {
                                streamToName.put(name, layerName);
                            } else {
                                streamToName.put(name, oldValue + ',' + layerName);
                            }
                        }
                    }

                    //must be done as can be defined in order with default and then ON/OFF as well
                    if (status == PdfDictionary.ON) {
                        layersEnabled.put(layerName, "x");
                    } else {
                        layersEnabled.remove(layerName);
                    }
                }
            } else {
                addLayer(status, (Object[]) layer[ii], layerName);
            }
        }

        if (debug) {
            final int len = padding.length();

            if (len > 3) {
                padding = padding.substring(0, len - 3);
            }
        }
    }

    private void addLayer(final int status, final byte[][] layer, final String parentName) {

        if (layer == null) {
            return;
        }

        String ref, name;

        PdfObject nextObject;

        for (final byte[] aLayer : layer) {

            ref = new String(aLayer);
            name = refToPropertyID.get(ref);
            nextObject = propertyMap.get(ref);

            if (nextObject != null) {

                layerCount++;

                String layerName = nextObject.getTextStreamValue(PdfDictionary.Name);

                if (parentName != null) {
                    layerName = layerName + deliminator + parentName;
                }

                //pick up full name set by Order
                if (status == PdfDictionary.ON || status == PdfDictionary.OFF) {
                    final String possName = refTolayerName.get(ref);
                    if (possName != null) {
                        layerName = possName;
                    }
                }

                if (debug) {
                    System.out.println(padding + "[layer0] add layer=" + layerName + " ref=" + ref + " parent=" + parentName + " refToLayerName=" + refTolayerName.get(ref) + " status=" + status);
                }

                if (refTolayerName.get(ref) == null) {

                    refTolayerName.put(ref, layerName);

                    layerNames.put(layerName, status);
                }

                if (streamToName.get(name) != null) { //ignore if done
                } else if (name.indexOf(',') == -1) {
                    final String oldValue = streamToName.get(name);
                    if (oldValue == null) {
                        streamToName.put(name, layerName);
                    } else {
                        streamToName.put(name, oldValue + ',' + layerName);
                    }
                } else {
                    final StringTokenizer names = new StringTokenizer(name, ",");
                    while (names.hasMoreTokens()) {
                        name = names.nextToken();
                        final String oldValue = streamToName.get(name);
                        if (oldValue == null) {
                            streamToName.put(name, layerName);
                        } else {
                            streamToName.put(name, oldValue + ',' + layerName);
                        }
                    }
                }

                //must be done as can be defined in order with default and then ON/OFF as well
                if (status == PdfDictionary.ON) {
                    layersEnabled.put(layerName, "x");
                } else {
                    layersEnabled.remove(layerName);
                }

                layersTested.put(layerName, "x");
            }
        }
    }

    private void setAS(final byte[][] AS, final PdfObjectReader currentPdfFile) {

        if (AS == null) {
            return;
        }

        int event;

        String ref, name, layerName;

        byte[][] OCGs;

        PdfObject nextObject;

        for (final byte[] A : AS) {

            //can also be a direct command which is not yet implemented
            if (A == null) {
                continue;
            }

            ref = new String(A);

            nextObject = new OCObject(ref);
            if (A[0] == '<') {
                nextObject.setStatus(PdfObject.UNDECODED_DIRECT);
            } else {
                nextObject.setStatus(PdfObject.UNDECODED_REF);
            }

            //must be done AFTER setStatus()
            nextObject.setUnresolvedData(A, PdfDictionary.AS);
            currentPdfFile.checkResolved(nextObject);

            event = nextObject.getParameterConstant(PdfDictionary.Event);
            if (nextObject != null) {

                if (event == PdfDictionary.View) {
                    OCGs = nextObject.getKeyArray(PdfDictionary.OCGs);

                    if (OCGs != null) {

                        for (final byte[] OCG : OCGs) {

                            ref = new String(OCG);
                            nextObject = new OCObject(ref);
                            if (OCG[0] == '<') {
                                nextObject.setStatus(PdfObject.UNDECODED_DIRECT);
                            } else {
                                nextObject.setStatus(PdfObject.UNDECODED_REF);
                            }

                            //must be done AFTER setStatus()
                            nextObject.setUnresolvedData(OCG, PdfDictionary.OCGs);
                            currentPdfFile.checkResolved(nextObject);

                            layerName = nextObject.getTextStreamValue(PdfDictionary.Name);
                            name = refToPropertyID.get(ref);

                            if (name == null && refToPropertyID.isEmpty()) { //23911 - include implicit value if Properties not set
                                name = "MC0";
                            }

                            streamToName.put(name, layerName);

                            //System.out.println((char)OCGs[jj][0]+" "+ref+" "+" "+nextObject+" "+nextObject.getTextStreamValue(PdfDictionary.Name));

                            final PdfObject usageObj = nextObject.getDictionary(PdfDictionary.Usage);

                            if (usageObj != null) {
                                final PdfObject zoomObj = usageObj.getDictionary(PdfDictionary.Zoom);

                                //set zoom values
                                if (zoomObj != null) {
                                    final float min = zoomObj.getFloatNumber(PdfDictionary.min);
                                    if (min != 0) {
                                        minScale.put(layerName, min);
                                    }
                                    final float max = zoomObj.getFloatNumber(PdfDictionary.max);

                                    if (max != 0) {
                                        maxScale.put(layerName, max);
                                    }
                                }
                            }
                        }
                    }
                }
                //layerCount++;

                //String layerName=nextObject.getTextStreamValue(PdfDictionary.Name);

                //if(debug)
                //System.out.println("[AS] add AS="+layerName);

                //refTolayerName.put(ref,layerName);

                //layerNames.put(layerName,new Integer(status));

//                if(layerName.indexOf(",")==-1){
//                    String oldValue=(String)streamToName.get(layerName);
//                    if(oldValue==null)
//                        streamToName.put(layerName,layerName);
//                    else
//                        streamToName.put(layerName,oldValue+","+layerName);
//                }else{
//                    StringTokenizer names=new StringTokenizer(layerName,",");
//                    while(names.hasMoreTokens()){
//                        layerName=names.nextToken();
//                        String oldValue=(String)streamToName.get(layerName);
//                        if(oldValue==null)
//                            streamToName.put(layerName,layerName);
//                        else
//                            streamToName.put(layerName,oldValue+","+layerName);
//                    }
//                }


            }
        }
    }

    private void setLocks(final PdfObjectReader currentPdfFile, final byte[][] layer) {

        if (layer == null) {
            return;
        }

        for (final byte[] aLayer : layer) {

            final String nextValue = new String(aLayer);

            final PdfObject nextObject = new OCObject(nextValue);

            currentPdfFile.readObject(nextObject);

            final String layerName = nextObject.getTextStreamValue(PdfDictionary.Name);

            layerLocks.put(layerName, "x");

        }
    }

    public Map getMetaData() {
        return Collections.unmodifiableMap(metaData);
    }

    public Object[] getDisplayTree() {

        if (order != null) {
            return order;
        } else {
            return getNames();
        }
    }

    /**
     * return list of layer names as String array
     */
    private String[] getNames() {

        final int count = layerNames.size();
        final String[] nameList = new String[count];

        final Iterator names = layerNames.keySet().iterator();

        int jj = 0;
        while (names.hasNext()) {
            nameList[jj] = names.next();
            jj++;
        }


        return nameList;
    }

    /**
     * will display only these layers and hide all others and will override
     * any constraints.
     * If you pass null in, all layers will be removed
     *
     * @param layerNames is of type String[]
     */
    @SuppressWarnings("UnusedDeclaration")
    public void setVisibleLayers(final String[] layerNames) {

        layersEnabled.clear();

        if (layerNames != null) {

            for (final String layerName : layerNames) {
                layersEnabled.put(layerName, "x");
            }
        }

        //flag it has been altered
        changesMade = true;
    }


    /**
     * Used internally only. takes name in Stream (ie MC7 and works out if we
     * need to decode) if isID==true.
     *
     * @param name is of type String
     * @param isID is of type boolean
     * @return type boolean
     */
    public boolean decodeLayer(final String name, final boolean isID) {

        if (layerCount == 0) {
            return true;
        }

        boolean isLayerVisible = false;

        String layerName = name;

        //see if match found otherwise assume name
        if (isID) {
            final String mappedName = streamToName.get(name);

            if (mappedName != null) {
                layerName = mappedName;
            }
        }

        if (layerName == null) {
            return false;
        } else {

            //if multiple layers  them comma separated list
            if (layerName.indexOf(',') == -1) {
                isLayerVisible = layersEnabled.containsKey(layerName);

                if (isLayerVisible) {
                    isLayerVisible = hiddenByParent(isLayerVisible, layerName);
                }

            } else {
                final StringTokenizer names = new StringTokenizer(layerName, ",");
                while (names.hasMoreTokens()) {

                    final String nextName = names.nextToken();
                    isLayerVisible = layersEnabled.containsKey(nextName);

                    if (isLayerVisible) {
                        isLayerVisible = hiddenByParent(isLayerVisible, nextName);
                    }

                    if (isLayerVisible) //exit on first match
                    {
                        break;
                    }
                }
            }

            if (debug) {
                System.out.println("[isVisible] " + name + " decode=" + isLayerVisible + " enabled=" + layersEnabled + " layerName=" + layerName + " isEnabled=" + this.layersEnabled);
            }
            //System.out.println("stream="+streamToName);

            return isLayerVisible;
        }
    }

    //check not disabled by Parent up tree        
    private boolean hiddenByParent(boolean layerVisible, String layerName) {

        int id = layerName.indexOf(deliminator);

        if (layerVisible && id != -1) {

            String parent = layerName.substring(id + 1, layerName.length());

            while (parent != null && layerVisible && isLayerName(parent)) {

                layerVisible = decodeLayer(parent, false);

                layerName = parent;
                id = layerName.indexOf(deliminator);
                if (id == -1) {
                    parent = null;
                } else {
                    parent = layerName.substring(id + 1, layerName.length());
                }
            }
        }

        return layerVisible;
    }

    /**
     * Switch on/off layers based on Zoom.
     *
     * @param scaling is of type float
     * @return is of type boolean
     */
    public boolean setZoom(final float scaling) {

        String layerName;
        final Iterator minZoomLayers = minScale.keySet().iterator();
        while (minZoomLayers.hasNext()) {

            layerName = minZoomLayers.next();
            final Float minScalingValue = minScale.get(layerName);

            //Zoom off
            if (minScalingValue != null) {

                //System.out.println(layerName+" "+scaling+" "+minScalingValue);

                if (scaling < minScalingValue) {
                    layersEnabled.remove(layerName);
                    changesMade = true;
                } else if (!layersEnabled.containsKey(layerName)) {
                    layersEnabled.put(layerName, "x");
                    changesMade = true;
                }
            }
        }


        final Iterator maxZoomLayers = maxScale.keySet().iterator();
        while (maxZoomLayers.hasNext()) {

            layerName = minZoomLayers.next();
            final Float maxScalingValue = maxScale.get(layerName);
            if (maxScalingValue != null) {
                if (scaling > maxScalingValue) {
                    layersEnabled.remove(layerName);
                    changesMade = true;
                } else if (!layersEnabled.containsKey(layerName)) {
                    layersEnabled.put(layerName, "x");
                    changesMade = true;
                }
            }
        }

        return changesMade;
    }

    public boolean isVisible(final String layerName) {

        return layersEnabled.containsKey(layerName);
    }

    public void setVisiblity(final String layerName, final boolean isVisible) {

        if (debug) {
            System.out.println("[layer] setVisiblity=" + layerName + " isVisible=" + isVisible);
        }

        if (isVisible) {
            layersEnabled.put(layerName, "x");

            //disable any other layers
            final String layersToDisable = RBconstraints.get(layerName);
            if (layersToDisable != null) {
                final StringTokenizer layers = new StringTokenizer(layersToDisable, ",");
                while (layers.hasMoreTokens()) {
                    layersEnabled.remove(layers.nextToken());
                }
            }
        } else {
            layersEnabled.remove(layerName);
        }

        //flag it has been altered
        changesMade = true;
    }

    public boolean isVisible(final PdfObject XObject) {

        //see if visible
        boolean isVisible = true;

        //if layer object attached see if should be visible
        final PdfObject layerObj = XObject.getDictionary(PdfDictionary.OC);

        if (layerObj != null) {

            String layerName = null;

            final PdfObject OCGs_as_dictionary = layerObj.getDictionary(PdfDictionary.OCGs);
            if (OCGs_as_dictionary != null) { //look at viewtate first
                
                /*
                 * NOTE!!!! Print and other modes not implemented yet
                 * (just added what I needed to fix 17584)
                 */

                //check viewmode flag
                final PdfObject usage = OCGs_as_dictionary.getDictionary(PdfDictionary.Usage);
                if (usage != null) {
                    final PdfObject viewState = usage.getDictionary(PdfDictionary.View);
                    if (viewState != null) {
                        isVisible = viewState.getNameAsConstant(PdfDictionary.ViewState) == PdfDictionary.ON;
                    }
                }
            } else {
                final byte[][] OCGS = layerObj.getKeyArray(PdfDictionary.OCGs);

                if (OCGS != null) {
                    for (final byte[] OCG : OCGS) {
                        final String ref = new String(OCG);
                        layerName = getNameFromRef(ref);
                    }
                }

                if (layerName == null) {
                    layerName = layerObj.getTextStreamValue(PdfDictionary.Name);
                }

                if (layerName != null && isLayerName(layerName)) {
                    isVisible = isVisible(layerName);
                }
            }
        }

        return isVisible;
    }

    public boolean isLocked(final String layerName) {

        return layerLocks.containsKey(layerName);
    }

    /**
     * show if decoded version match visibility flags which can be altered by
     * user
     *
     * @return type boolean
     */
    public boolean getChangesMade() {
        return changesMade;
    }

    /**
     * show if is name of layer (as opposed to just label).
     *
     * @param name is of type String
     * @return is of type boolean
     */
    public boolean isLayerName(final String name) {
        return layerNames.containsKey(name);
    }

    /**
     * number of layers setup.
     *
     * @return is of type int.
     */
    public int getLayersCount() {
        return layerCount;
    }

    public String getNameFromRef(final String ref) {
        return refTolayerName.get(ref);
    }

//    public void setScaling(float scaling) {
//        this.scaling=scaling;
//    }

    /**
     * JS
     * Gets an array of OCG objects found on a specified page.
     *
     * @return - An array of OCG objects or null if no OCGs are present.
     */
    public Object[] getOCGs() {

        //return once initialised
        if (layers != null) {
            return layers;
        }

        final int count = layerNames.size();

        //create array of values with access to this so we can reset
        final Layer[] layers = new Layer[count];

        final Iterator layersIt = layerNames.keySet().iterator();
        int ii = 0;
        String name;
        while (layersIt.hasNext()) {
            name = layersIt.next();

            layers[ii] = new Layer(name, this);
            ii++;
        }

        return layers;
    }


    public void addJScommand(final String name, final String js) {

        if (jsCommands == null) {
            jsCommands = new HashMap();
        }

        //add to list to execute
        jsCommands.put(name, js);
    }

    public Iterator getJSCommands() {

        if (jsCommands != null) {
            final Iterator names = this.jsCommands.keySet().iterator();
            final Map visibleJSCommands = new HashMap();

            while (names.hasNext()) {
                final String name = names.next();
                if (this.isVisible(name)) {
                    visibleJSCommands.put(jsCommands.get(name), "x");
                }
            }

            return visibleJSCommands.keySet().iterator();
        } else {
            return null;
        }
    }

    public int getOCpageNumber() {
        return OCpageNumber;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy