0

I am trying to implement functionality to allow user to add markups to existing layers in a pdf. Here is the code that I am using to draw lines on to a layer in a pdf:

PDResources  resources = page.findResources();
PDPropertyList props = resources.getProperties();        
COSName resourceName = getLayerResourceName("Superimposed3", resources, props);
PDPageContentStream cs1 = new PDPageContentStream(document, page, true, false);
cs1.beginMarkedContentSequence(COSName.OC, resourceName);
cs1.setStrokingColor(0, 0, 255);
cs1.setLineWidth(0.8F);
cs1.drawLine(100,100,250,200);
cs1.endMarkedContentSequence();
cs1.close();

I am using beginMarkedContentSequence instead of beginMarkedContent as I am using pdfbox 1.8 version and 2.0.5 version is not available for .net. Here, is my function to get resource name for a layer:

 private static COSName getLayerResourceName(string layerName,PDResources resources,PDPropertyList props)
        {
            int index = 0;
            COSName resourceName = COSName.getPDFName("MC"+ index);
            PDOptionalContentGroup ocg = props.getOptionalContentGroup(resourceName);
            if (ocg != null && (ocg.getName() == layerName))
            {
                return resourceName;    
            }
            else if (ocg == null)
            {
                return null;
            }
            else
            { 
                resourceName = null;
                index++;
                bool exitFlag = false;
                while (!exitFlag)
                {
                    resourceName = COSName.getPDFName("MC" + index);
                    ocg = props.getOptionalContentGroup(resourceName);
                    if (ocg == null)
                    {
                        exitFlag = true;
                        resourceName = null;
                    }
                    else if (ocg.getName() == layerName)
                    {
                        exitFlag = true;
                    }
                    else
                    {
                        index++;
                    }
                }
            }
            return resourceName;
        }

The above functions only works for those layers which were added using the LayerUtility.appendFormAsLayer function. But it doesn't work for those layers which were created using the following code:

PDOptionalContentProperties ocprops = document.getDocumentCatalog().getOCProperties();
PDOptionalContentGroup newGroup = new PDOptionalContentGroup("Superimposed2");
PDOptionalContentGroup newGroup1 = new PDOptionalContentGroup("Superimposed3");
ocprops.addGroup(newGroup);
ocprops.addGroup(newGroup1);

So, shall I add "MC" value in properties of page myself while, creating layer, or is there another way to get resource name for such layers.

V K
  • 1,645
  • 3
  • 26
  • 57
  • Your question is not really clear, what is "props" in the first code line? See also the source code of LayerUtility.appendFormAsLayer - the "MCn" name is chosen as the first one that isn't in the Properties resource dictionary. (Search for "Find first free resource name"). Your last 5 lines of code don't add anything to the Properties resource dictionary. This is done at the line "Put mapping for our new layer/OCG" in the PDFBox source. – Tilman Hausherr Apr 11 '17 at 13:51
  • @TilmanHausherr props is the PDPropertyList of the page.Also, if there is a layer , created using some random pdf editor, which doesn't have any mapping defined in the propertylist. How do I get resource name for it? – V K Apr 11 '17 at 14:18
  • 1) then don't forget to add your new "MCn" to the props. 2) ouch, the implementation is crappy in 1.8. `resources.getProperties()` is a dictionary, so you can get it with `resources.getProperties().getCOSObject()`, cast to COSDictionary, then get the existing keys with `keySet()`. – Tilman Hausherr Apr 11 '17 at 14:27
  • @TilmanHausherr You mean in case I don't find resource name for a layer, then I add a new mapping for it myself. – V K Apr 11 '17 at 14:31
  • Yes. That is what LayerUtility does below the comment "Put mapping for our new layer/OCG": `props.putMapping(resourceName, layer);`, with layer being an `PDOptionalContentGroup`. – Tilman Hausherr Apr 11 '17 at 14:33
  • 1
    You can actually take the easy route and create a new OCG resource name each time you add something to that OCG, cf. my answer to [your other question in this context](http://stackoverflow.com/q/43275212/1729265). Of course, if you very often add small bits of information to the same page and OCG, you should indeed try and find an existing OCG resource name for your OCG. – mkl Apr 11 '17 at 21:47

0 Answers0