mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-07-16 05:11:17 +08:00
157 lines
6.3 KiB
C#
157 lines
6.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UglyToad.PdfPig.Tokens;
|
|
|
|
namespace UglyToad.PdfPig.Content
|
|
{
|
|
/// <summary>
|
|
/// An optional content group is a dictionary representing a collection of graphics
|
|
/// that can be made visible or invisible dynamically by users of viewers applications.
|
|
/// </summary>
|
|
public class OptionalContentGroupElement
|
|
{
|
|
/// <summary>
|
|
/// The type of PDF object that this dictionary describes.
|
|
/// <para>Must be OCG for an optional content group dictionary.</para>
|
|
/// </summary>
|
|
public string Type { get; }
|
|
|
|
/// <summary>
|
|
/// The name of the optional content group, suitable for presentation in a viewer application's user interface.
|
|
/// </summary>
|
|
public string Name { get; }
|
|
|
|
/// <summary>
|
|
/// A single name or an array containing any combination of names.
|
|
/// <para>Default value is 'View'.</para>
|
|
/// </summary>
|
|
public IReadOnlyList<string> Intent { get; }
|
|
|
|
/// <summary>
|
|
/// A usage dictionary describing the nature of the content controlled by the group.
|
|
/// </summary>
|
|
public IReadOnlyDictionary<string, IToken> Usage { get; }
|
|
|
|
/// <summary>
|
|
/// Underlying <see cref="MarkedContentElement"/>.
|
|
/// </summary>
|
|
public MarkedContentElement MarkedContent { get; }
|
|
|
|
internal OptionalContentGroupElement(MarkedContentElement markedContentElement)
|
|
{
|
|
MarkedContent = markedContentElement;
|
|
|
|
// Type - Required
|
|
if (markedContentElement.Properties.TryGet(NameToken.Type, out NameToken type))
|
|
{
|
|
Type = type.Data;
|
|
}
|
|
else if (markedContentElement.Properties.TryGet(NameToken.Type, out StringToken typeStr))
|
|
{
|
|
Type = typeStr.Data;
|
|
}
|
|
else
|
|
{
|
|
throw new ArgumentException($"Cannot parse optional content's {nameof(Type)} from {nameof(markedContentElement.Properties)}. This is a required field.", nameof(markedContentElement.Properties));
|
|
}
|
|
|
|
switch (Type)
|
|
{
|
|
case "OCG": // Optional content group dictionary
|
|
// Name - Required
|
|
if (markedContentElement.Properties.TryGet(NameToken.Name, out NameToken name))
|
|
{
|
|
Name = name.Data;
|
|
}
|
|
else if (markedContentElement.Properties.TryGet(NameToken.Name, out StringToken nameStr))
|
|
{
|
|
Name = nameStr.Data;
|
|
}
|
|
else
|
|
{
|
|
throw new ArgumentException($"Cannot parse optional content's {nameof(Name)} from {nameof(markedContentElement.Properties)}. This is a required field.", nameof(markedContentElement.Properties));
|
|
}
|
|
|
|
// Intent - Optional
|
|
if (markedContentElement.Properties.TryGet(NameToken.Intent, out NameToken intentName))
|
|
{
|
|
Intent = new string[] { intentName.Data };
|
|
}
|
|
else if (markedContentElement.Properties.TryGet(NameToken.Intent, out StringToken intentStr))
|
|
{
|
|
Intent = new string[] { intentStr.Data };
|
|
}
|
|
else if (markedContentElement.Properties.TryGet(NameToken.Intent, out ArrayToken intentArray))
|
|
{
|
|
List<string> intentList = new List<string>();
|
|
foreach (var token in intentArray.Data)
|
|
{
|
|
if (token is NameToken nameA)
|
|
{
|
|
intentList.Add(nameA.Data);
|
|
}
|
|
else if (token is StringToken strA)
|
|
{
|
|
intentList.Add(strA.Data);
|
|
}
|
|
else
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
Intent = intentList;
|
|
}
|
|
else
|
|
{
|
|
// Default value is 'View'.
|
|
Intent = new string[] { "View" };
|
|
}
|
|
|
|
// Usage - Optional
|
|
if (markedContentElement.Properties.TryGet(NameToken.Usage, out DictionaryToken usage))
|
|
{
|
|
this.Usage = usage.Data;
|
|
}
|
|
break;
|
|
|
|
case "OCMD":
|
|
// OCGs - Optional
|
|
if (markedContentElement.Properties.TryGet(NameToken.Ocgs, out DictionaryToken ocgsD))
|
|
{
|
|
// dictionary or array
|
|
throw new NotImplementedException($"{NameToken.Ocgs}");
|
|
}
|
|
else if (markedContentElement.Properties.TryGet(NameToken.Ocgs, out ArrayToken ocgsA))
|
|
{
|
|
// dictionary or array
|
|
throw new NotImplementedException($"{NameToken.Ocgs}");
|
|
}
|
|
|
|
// P - Optional
|
|
if (markedContentElement.Properties.TryGet(NameToken.P, out NameToken p))
|
|
{
|
|
throw new NotImplementedException($"{NameToken.P}");
|
|
}
|
|
|
|
// VE - Optional
|
|
if (markedContentElement.Properties.TryGet(NameToken.VE, out ArrayToken ve))
|
|
{
|
|
throw new NotImplementedException($"{NameToken.VE}");
|
|
}
|
|
break;
|
|
|
|
default:
|
|
throw new ArgumentException($"Unknown Optional Content of type '{Type}' not known.", nameof(Type));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <inheritdoc/>
|
|
/// </summary>
|
|
public override string ToString()
|
|
{
|
|
return $"{Type} - {Name} [{string.Join(",", Intent)}]: {MarkedContent?.ToString()}";
|
|
}
|
|
}
|
|
}
|