mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-07-15 21:45:38 +08:00
Move GetOptionalContents into Experimental and get optional marked content recursively
This commit is contained in:
parent
78e6e582cd
commit
4cd1f60f5b
Binary file not shown.
@ -1,4 +1,6 @@
|
||||
using Xunit;
|
||||
using System;
|
||||
using UglyToad.PdfPig.Tokens;
|
||||
using Xunit;
|
||||
|
||||
namespace UglyToad.PdfPig.Tests.Integration
|
||||
{
|
||||
@ -10,7 +12,7 @@ namespace UglyToad.PdfPig.Tests.Integration
|
||||
using (var document = PdfDocument.Open(IntegrationHelpers.GetDocumentPath("odwriteex.pdf")))
|
||||
{
|
||||
var page = document.GetPage(1);
|
||||
var oc = page.GetOptionalContents();
|
||||
var oc = page.ExperimentalAccess.GetOptionalContents();
|
||||
|
||||
Assert.Equal(3, oc.Count);
|
||||
|
||||
@ -23,5 +25,30 @@ namespace UglyToad.PdfPig.Tests.Integration
|
||||
Assert.Equal(1, oc["Text"].Count);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MarkedOptionalContentRecursion()
|
||||
{
|
||||
using (var document = PdfDocument.Open(IntegrationHelpers.GetDocumentPath("Layer pdf - 322_High_Holborn_building_Brochure.pdf")))
|
||||
{
|
||||
var page1 = document.GetPage(1);
|
||||
var oc1 = page1.ExperimentalAccess.GetOptionalContents();
|
||||
Assert.Equal(16, oc1.Count);
|
||||
Assert.Contains("NEW ARRANGEMENT", oc1);
|
||||
|
||||
var page2 = document.GetPage(2);
|
||||
var oc2 = page2.ExperimentalAccess.GetOptionalContents();
|
||||
Assert.Equal(15, oc2.Count);
|
||||
Assert.DoesNotContain("NEW ARRANGEMENT", oc2);
|
||||
Assert.Contains("WDL Shell text", oc2);
|
||||
Assert.Equal(2, oc2["WDL Shell text"].Count);
|
||||
|
||||
var page3 = document.GetPage(3);
|
||||
var oc3 = page3.ExperimentalAccess.GetOptionalContents();
|
||||
Assert.Equal(15, oc3.Count);
|
||||
Assert.Contains("WDL Shell text", oc3);
|
||||
Assert.Equal(2, oc3["WDL Shell text"].Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace UglyToad.PdfPig.Content
|
||||
/// <summary>
|
||||
/// A usage dictionary describing the nature of the content controlled by the group.
|
||||
/// </summary>
|
||||
public IDictionary<string, object> Usage { get; }
|
||||
public IReadOnlyDictionary<string, IToken> Usage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Underlying <see cref="MarkedContentElement"/>.
|
||||
@ -110,7 +110,7 @@ namespace UglyToad.PdfPig.Content
|
||||
// Usage - Optional
|
||||
if (markedContentElement.Properties.TryGet(NameToken.Usage, out DictionaryToken usage))
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
this.Usage = usage.Data;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -119,29 +119,29 @@ namespace UglyToad.PdfPig.Content
|
||||
if (markedContentElement.Properties.TryGet(NameToken.Ocgs, out DictionaryToken ocgsD))
|
||||
{
|
||||
// dictionary or array
|
||||
throw new NotImplementedException();
|
||||
throw new NotImplementedException($"{NameToken.Ocgs}");
|
||||
}
|
||||
else if (markedContentElement.Properties.TryGet(NameToken.Ocgs, out ArrayToken ocgsA))
|
||||
{
|
||||
// dictionary or array
|
||||
throw new NotImplementedException();
|
||||
throw new NotImplementedException($"{NameToken.Ocgs}");
|
||||
}
|
||||
|
||||
// P - Optional
|
||||
if (markedContentElement.Properties.TryGet(NameToken.P, out NameToken p))
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
throw new NotImplementedException($"{NameToken.P}");
|
||||
}
|
||||
|
||||
// VE - Optional
|
||||
if (markedContentElement.Properties.TryGet(NameToken.VE, out ArrayToken ve))
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
throw new NotImplementedException($"{NameToken.VE}");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Unknown Optional Content of type '{Type}'.", nameof(Type));
|
||||
throw new ArgumentException($"Unknown Optional Content of type '{Type}' not known.", nameof(Type));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
using Util.JetBrains.Annotations;
|
||||
using Tokenization.Scanner;
|
||||
using Graphics;
|
||||
using System.Linq;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the content and provides access to methods of a single page in the <see cref="PdfDocument"/>.
|
||||
@ -166,11 +167,6 @@
|
||||
/// </summary>
|
||||
public IReadOnlyList<MarkedContentElement> GetMarkedContents() => Content.GetMarkedContents();
|
||||
|
||||
/// <summary>
|
||||
/// Gets any optional content on the page.
|
||||
/// </summary>
|
||||
public IDictionary<string, IReadOnlyList<OptionalContentGroupElement>> GetOptionalContents() => Content.GetOptionalContents();
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to useful members which will change in future releases.
|
||||
/// </summary>
|
||||
@ -198,6 +194,42 @@
|
||||
{
|
||||
return annotationProvider.GetAnnotations();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets any optional content on the page.
|
||||
/// <para>Does not handle XObjects and annotations for the time being.</para>
|
||||
/// </summary>
|
||||
public IDictionary<string, IReadOnlyList<OptionalContentGroupElement>> GetOptionalContents()
|
||||
{
|
||||
// 4.10.2
|
||||
// Optional content in content stream
|
||||
var mc = page.Content?.GetMarkedContents();
|
||||
|
||||
List<OptionalContentGroupElement> mcesOptional = new List<OptionalContentGroupElement>();
|
||||
GetOptionalContentsRecursively(mc, ref mcesOptional);
|
||||
|
||||
// Optional content in XObjects and annotations
|
||||
// TO DO
|
||||
//var annots = GetAnnotations().ToList();
|
||||
|
||||
return mcesOptional.GroupBy(oc => oc.Name).ToDictionary(g => g.Key, g => g.ToList() as IReadOnlyList<OptionalContentGroupElement>);
|
||||
}
|
||||
|
||||
private void GetOptionalContentsRecursively(IReadOnlyList<MarkedContentElement> markedContentElements, ref List<OptionalContentGroupElement> mcesOptional)
|
||||
{
|
||||
foreach (var mce in markedContentElements)
|
||||
{
|
||||
if (mce.Tag == "OC")
|
||||
{
|
||||
mcesOptional.Add(new OptionalContentGroupElement(mce));
|
||||
// we don't recurse
|
||||
}
|
||||
else if (mce.Children?.Count > 0)
|
||||
{
|
||||
GetOptionalContentsRecursively(mce.Children, ref mcesOptional);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,24 +67,5 @@
|
||||
}
|
||||
|
||||
public IReadOnlyList<MarkedContentElement> GetMarkedContents() => markedContents;
|
||||
|
||||
public IDictionary<string, IReadOnlyList<OptionalContentGroupElement>> GetOptionalContents()
|
||||
{
|
||||
const string ocTag = "OC";
|
||||
|
||||
List<OptionalContentGroupElement> optionalContent = new List<OptionalContentGroupElement>();
|
||||
|
||||
// 4.10.2
|
||||
// Optional content in content stream
|
||||
foreach (var omc in GetMarkedContents().Where(mc => mc.Tag == ocTag))
|
||||
{
|
||||
optionalContent.Add(new OptionalContentGroupElement(omc));
|
||||
}
|
||||
|
||||
// Optional content in XObjects and annotations
|
||||
// TO DO
|
||||
|
||||
return optionalContent.GroupBy(oc => oc.Name).ToDictionary(g => g.Key, g => g.ToList() as IReadOnlyList<OptionalContentGroupElement>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user