logo
Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

New Topic Post Reply
Options
Go to last post Go to first unread
MRavenscroft  
#1 Posted : Monday, October 23, 2017 8:02:29 AM(UTC)
Quote
MRavenscroft

Rank: Newbie

Groups: Registered
Joined: 10/23/2017(UTC)
Posts: 4
United Kingdom

Thanks: 2 times
Hi,

I'm trying to find which OCG each PageObject belongs to.
I've followed the description from here to find all of the OCGs in the document and whether they are displayed, but that doesn't provide the information about the contents of each group

I've had a look at where that information is in the PDF standard, and it seems to be referenced via an optional "/OC" tag for each object.
Do you know how I would go about getting this tag for a specific page object? Is there a way to get the raw data or dictionary for each PageObject from PDFium?

Thanks,
Mike
Paul Rayman  
#2 Posted : Monday, October 23, 2017 9:11:30 AM(UTC)
Quote
Paul Rayman

Rank: Administration

Groups: Administrators
Joined: 1/5/2016(UTC)
Posts: 1,035

Thanks: 5 times
Was thanked: 122 time(s) in 119 post(s)
It looks like it is possible.
Could you please provide such PDF file?

MRavenscroft  
#3 Posted : Monday, October 23, 2017 10:13:53 AM(UTC)
Quote
MRavenscroft

Rank: Newbie

Groups: Registered
Joined: 10/23/2017(UTC)
Posts: 4
United Kingdom

Thanks: 2 times
Thank you for the quick reply, that would be very helpful.

I've trimmed down one of my example PDFs and have attached it: SimplifiedExamplePdf.pdf (23kb) downloaded 28 time(s)..
It has a number of drawing paths stored across several different OCGs. The original has various bits of text and annotations in different layers as well, but the structure was essentially the same

The older examples from here all have similar layer structures too

Mike
Paul Rayman  
#4 Posted : Tuesday, October 24, 2017 7:23:39 AM(UTC)
Quote
Paul Rayman

Rank: Administration

Groups: Administrators
Joined: 1/5/2016(UTC)
Posts: 1,035

Thanks: 5 times
Was thanked: 122 time(s) in 119 post(s)
I have checked, you can get the name of the optional content (like "ABA-WD-WALL HATCH") for each page object.
But some improvements of the class library are required. I passed this issue to the development team. We will release this in a couple days I hope.
MRavenscroft  
#5 Posted : Tuesday, October 24, 2017 7:41:54 AM(UTC)
Quote
MRavenscroft

Rank: Newbie

Groups: Registered
Joined: 10/23/2017(UTC)
Posts: 4
United Kingdom

Thanks: 2 times
That would fit what we need perfectly, thanks. I'll wait for the update

Mike
Paul Rayman  
#6 Posted : Wednesday, October 25, 2017 8:27:35 AM(UTC)
Quote
Paul Rayman

Rank: Administration

Groups: Administrators
Joined: 1/5/2016(UTC)
Posts: 1,035

Thanks: 5 times
Was thanked: 122 time(s) in 119 post(s)
Done!
https://forum.patagames.com/posts/t390-Version-3-11-1-2704-was-released-on-Oct-25--2017

Please look at an example below
Code:

var doc = PdfDocument.Load(@"d:\1\SimplifiedExamplePdf.pdf");
var page = doc.Pages[0];
foreach(var obj in page.PageObjects)
{
	foreach(var mc in obj.MarkedContent)
	{
		if(mc.Tag=="OC") //This is an optional content
		{
			if (mc.Parameters != null)
				Console.WriteLine((mc.Parameters["Name"] as PdfTypeString).UnicodeString);
		}
	}
}


The output of that code is
Code:

...
ABA-WD-WALL HATCH
ABA-WD-WALL HATCH
ABA-WD-WALL HATCH
ABA-WD-WALL HATCH
ABA-WD-WALL PLASTER
ABA-WD-WALL PLASTER
ABA-WD-WALL PLASTER
ABA-WD-WALL PLASTER
ABA-WD-WALL PLASTER
ABA-WD-WALL PLASTER
ABA-WD-DOOR EXERNAL
ABA-WD-DOOR EXERNAL
ABA-WD-DOOR EXERNAL
ABA-WD-DOOR EXERNAL
ABA-WD-DOOR EXERNAL
ABA-WD-DOOR EXERNAL
ABA-WD-DOOR EXERNAL
ABA-WD-WINDOWS
ABA-WD-WALL EXTERNAL
ABA-WD-WALL EXTERNAL
ABA-WD-WINDOWS
ABA-WD-WINDOWS
ABA-WD-WINDOWS
ABA-WD-WALL PLASTER
ABA-WD-WINDOWS
ABA-WD-WINDOWS
ABA-WD-WALL HATCH
...

thanks 1 user thanked Paul Rayman for this useful post.
MRavenscroft on 10/25/2017(UTC)
MRavenscroft  
#7 Posted : Wednesday, October 25, 2017 8:46:26 AM(UTC)
Quote
MRavenscroft

Rank: Newbie

Groups: Registered
Joined: 10/23/2017(UTC)
Posts: 4
United Kingdom

Thanks: 2 times
Excellent! I've tested it and it works perfectly.
Many thanks for your help and for adding it so quickly

Mike
Paul Rayman  
#8 Posted : Wednesday, October 25, 2017 8:53:47 AM(UTC)
Quote
Paul Rayman

Rank: Administration

Groups: Administrators
Joined: 1/5/2016(UTC)
Posts: 1,035

Thanks: 5 times
Was thanked: 122 time(s) in 119 post(s)
You also may find the dictionary inside "OCGs" array by a Dictionary.Handle

For example
Code:

static void Main(string[] args)
{
	PdfCommon.Initialize();
	var doc = PdfDocument.Load(@"d:\1\SimplifiedExamplePdf.pdf");
	var ocgObj = GetOcgFromObject(doc);
	var ocg = GetOcgFromOCProperties(doc, ocgObj.Handle);
	bool itIsTrue = ocgObj.Handle == ocg.Handle;
}

public static PdfTypeDictionary  GetOcgFromOCProperties(PdfDocument doc, IntPtr  handle)
{
	var root = doc.Root;
	var oc_prop = GetDictionary(root, "OCProperties", null, false);
	var ocgs = oc_prop["OCGs"] as PdfTypeArray;
	foreach (var item in ocgs)
	{
		var ocg = (item as PdfTypeIndirect).Direct as PdfTypeDictionary;
		if (ocg.Handle == handle)
		{
			return ocg;
		}
	}
	return null;
}

public static PdfTypeDictionary GetOcgFromObject(PdfDocument doc)
{
	var page = doc.Pages[0];
	foreach (var obj in page.PageObjects)
	{
		foreach (var mc in obj.MarkedContent)
		{
			if (mc.Tag == "OC") //This is an optional content
			{
				return mc.Parameters;
			}
		}
	}
	return null;
}

public static PdfTypeDictionary GetDictionary(PdfTypeDictionary parent, string entry, PdfIndirectList list = null, bool is_create = true)
{
	PdfTypeDictionary ret = null;
	if (!parent.ContainsKey(entry))
	{
		if (!is_create)
			throw new Exception(string.Format("The document does not have {0} entry", entry));

		ret = PdfTypeDictionary.Create();
		if (list != null)
		{
			list.Add(ret);
			parent.SetIndirectAt(entry, list, ret);
		}
		else
			parent.SetAt(entry, ret);
	}
	else if (parent[entry] is PdfTypeIndirect)
		ret = (parent[entry] as PdfTypeIndirect).Direct as PdfTypeDictionary;
	else if (parent[entry] is PdfTypeDictionary)
		ret = parent[entry] as PdfTypeDictionary;
	else
		throw new Exception(string.Format("'{0}' entry has unknown type", entry));

	return ret;
}
thanks 1 user thanked Paul Rayman for this useful post.
MRavenscroft on 10/25/2017(UTC)
Quick Reply Show Quick Reply
Users browsing this topic
New Topic Post Reply
Forum Jump  
You can post new topics in this forum.
You can reply to topics in this forum.
You can delete your posts in this forum.
You can edit your posts in this forum.
You cannot create polls in this forum.
You can vote in polls in this forum.