mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-09-21 04:17:57 +08:00
start adding retrieval of annotations
This commit is contained in:
38
src/UglyToad.PdfPig.Tests/Integration/CatGeneticsTests.cs
Normal file
38
src/UglyToad.PdfPig.Tests/Integration/CatGeneticsTests.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
namespace UglyToad.PdfPig.Tests.Integration
|
||||
{
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
public class CatGeneticsTests
|
||||
{
|
||||
private static string GetFilename()
|
||||
{
|
||||
return IntegrationHelpers.GetDocumentPath("cat-genetics.pdf");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanReadContent()
|
||||
{
|
||||
using (var document = PdfDocument.Open(GetFilename()))
|
||||
{
|
||||
var page = document.GetPage(1);
|
||||
|
||||
Assert.Contains("catus", page.Text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void CanGetAnnotations()
|
||||
{
|
||||
using (var document = PdfDocument.Open(GetFilename(), new ParsingOptions { UseLenientParsing = false }))
|
||||
{
|
||||
var page = document.GetPage(1);
|
||||
|
||||
var annotations = page.GetAnnotations().ToList();
|
||||
|
||||
Assert.NotEmpty(annotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
src/UglyToad.PdfPig.Tests/Integration/Documents/cat-genetics.pdf
Normal file
BIN
src/UglyToad.PdfPig.Tests/Integration/Documents/cat-genetics.pdf
Normal file
Binary file not shown.
52
src/UglyToad.PdfPig/Annotations/AnnotationFlags.cs
Normal file
52
src/UglyToad.PdfPig/Annotations/AnnotationFlags.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
namespace UglyToad.PdfPig.Annotations
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies characteristics of an annotation in a PDF or FDF document.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
internal enum AnnotationFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not display the annotation if it is not one of the standard annotation types.
|
||||
/// </summary>
|
||||
Invisible = 1 << 0,
|
||||
/// <summary>
|
||||
/// Do not display or print the annotation irrespective of type. Do not allow interaction.
|
||||
/// </summary>
|
||||
Hidden = 1 << 1,
|
||||
/// <summary>
|
||||
/// The annotation should be included when the document is physically printed.
|
||||
/// </summary>
|
||||
Print = 1 << 2,
|
||||
/// <summary>
|
||||
/// Do not zoom/scale the annotation as the zoom of the document is changed.
|
||||
/// </summary>
|
||||
NoZoom = 1 << 3,
|
||||
/// <summary>
|
||||
/// Do not rotate the annotation as the page is rotated.
|
||||
/// </summary>
|
||||
NoRotate = 1 << 4,
|
||||
/// <summary>
|
||||
/// Do not display the annotation in viewer applications as with <see cref="Hidden"/>, however allow the annotation to be printed if <see cref="Print"/> is set.
|
||||
/// </summary>
|
||||
NoView = 1 << 5,
|
||||
/// <summary>
|
||||
/// Allow the annotation to be displayed/printed if applicable but do not respond to user interaction, e.g. mouse clicks.
|
||||
/// </summary>
|
||||
ReadOnly = 1 << 6,
|
||||
/// <summary>
|
||||
/// Do not allow deleting the annotation or changing size/position but allow the contents to be modified.
|
||||
/// </summary>
|
||||
Locked = 1 << 7,
|
||||
/// <summary>
|
||||
/// Invert the meaning of the <see cref="NoView"/> flag.
|
||||
/// </summary>
|
||||
ToggleNoView = 1 << 8,
|
||||
/// <summary>
|
||||
/// Allow the annotation to be deleted, resized, moved or restyled but disallow changes to the annotation contents. Opposite to <see cref="Locked"/>.
|
||||
/// </summary>
|
||||
LockedContents = 1 << 9
|
||||
}
|
||||
}
|
360
src/UglyToad.PdfPig/Annotations/AnnotationProvider.cs
Normal file
360
src/UglyToad.PdfPig/Annotations/AnnotationProvider.cs
Normal file
@@ -0,0 +1,360 @@
|
||||
namespace UglyToad.PdfPig.Annotations
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Exceptions;
|
||||
using Geometry;
|
||||
using Parser.Parts;
|
||||
using Tokenization.Scanner;
|
||||
using Tokens;
|
||||
using Util;
|
||||
using Util.JetBrains.Annotations;
|
||||
|
||||
internal class AnnotationProvider
|
||||
{
|
||||
private readonly IPdfTokenScanner tokenScanner;
|
||||
private readonly DictionaryToken pageDictionary;
|
||||
private readonly bool isLenientParsing;
|
||||
|
||||
public AnnotationProvider(IPdfTokenScanner tokenScanner, DictionaryToken pageDictionary, bool isLenientParsing)
|
||||
{
|
||||
this.tokenScanner = tokenScanner ?? throw new ArgumentNullException(nameof(tokenScanner));
|
||||
this.pageDictionary = pageDictionary ?? throw new ArgumentNullException(nameof(pageDictionary));
|
||||
this.isLenientParsing = isLenientParsing;
|
||||
}
|
||||
|
||||
public IEnumerable<Annotation> GetAnnotations()
|
||||
{
|
||||
if (!pageDictionary.TryGet(NameToken.Annots, out IToken annotationsToken)
|
||||
|| !DirectObjectFinder.TryGet(annotationsToken, tokenScanner, out ArrayToken annotationsArray))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var token in annotationsArray.Data)
|
||||
{
|
||||
if (!DirectObjectFinder.TryGet(token, tokenScanner, out DictionaryToken annotationDictionary))
|
||||
{
|
||||
if (isLenientParsing)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new PdfDocumentFormatException($"The annotations dictionary contained an annotation which wasn't a dictionary: {token}.");
|
||||
}
|
||||
|
||||
if (!isLenientParsing && annotationDictionary.TryGet(NameToken.Type, out NameToken dictionaryType))
|
||||
{
|
||||
if (dictionaryType != NameToken.Annot)
|
||||
{
|
||||
throw new PdfDocumentFormatException($"The annotations dictionary contained a non-annotation type dictionary: {annotationDictionary}.");
|
||||
}
|
||||
}
|
||||
|
||||
var type = annotationDictionary.Get<NameToken>(NameToken.Subtype, tokenScanner);
|
||||
|
||||
var annotationType = type.ToAnnotationType();
|
||||
var rectangle = annotationDictionary.Get<ArrayToken>(NameToken.Rect, tokenScanner).ToRectangle();
|
||||
|
||||
string content = null;
|
||||
if (annotationDictionary.TryGet(NameToken.Contents, out var contentToken) && DirectObjectFinder.TryGet(contentToken, tokenScanner, out StringToken contentString))
|
||||
{
|
||||
content = contentString.Data;
|
||||
}
|
||||
|
||||
yield return new Annotation(annotationDictionary, rectangle, content, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class Annotation
|
||||
{
|
||||
/// <summary>
|
||||
/// The underlying PDF dictionary which this annotation was created from.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public DictionaryToken AnnotationDictionary { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The rectangle in user space units specifying the location to place this annotation on the page.
|
||||
/// </summary>
|
||||
public PdfRectangle Rectangle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The annotation text, or if the annotation does not display text, a description of the annotation's contents. Optional.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
public string Content { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of this annotation which should be unique per page. Optional.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The date and time the annotation was last modified, can be in any format. Optional.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
public string ModifiedDate { get; }
|
||||
|
||||
public AnnotationFlags Flags { get; } = (AnnotationFlags)0;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="Annotation"/>.
|
||||
/// </summary>
|
||||
public Annotation(DictionaryToken annotationDictionary, PdfRectangle rectangle, string content, string name, string modifiedDate)
|
||||
{
|
||||
AnnotationDictionary = annotationDictionary ?? throw new ArgumentNullException(nameof(annotationDictionary));
|
||||
Rectangle = rectangle;
|
||||
Content = content;
|
||||
Name = name;
|
||||
ModifiedDate = modifiedDate;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The standard annotation types in PDF documents.
|
||||
/// </summary>
|
||||
internal enum AnnotationType
|
||||
{
|
||||
/// <summary>
|
||||
/// A 'sticky note' style annotation displaying some text with open/closed pop-up state.
|
||||
/// </summary>
|
||||
Text = 0,
|
||||
/// <summary>
|
||||
/// A link to elsewhere in the document or an external application/web link.
|
||||
/// </summary>
|
||||
Link = 1,
|
||||
/// <summary>
|
||||
/// Displays text on the page. Unlike <see cref="Text"/> there is no associated pop-up.
|
||||
/// </summary>
|
||||
FreeText = 2,
|
||||
/// <summary>
|
||||
/// Display a single straight line on the page with optional line ending styles.
|
||||
/// </summary>
|
||||
Line = 3,
|
||||
/// <summary>
|
||||
/// Display a rectangle on the page.
|
||||
/// </summary>
|
||||
Square = 4,
|
||||
/// <summary>
|
||||
/// Display an ellipse on the page.
|
||||
/// </summary>
|
||||
Circle = 5,
|
||||
/// <summary>
|
||||
/// Display a closed polygon on the page.
|
||||
/// </summary>
|
||||
Polygon = 6,
|
||||
/// <summary>
|
||||
/// Display a set of connected lines on the page which is not a closed polygon.
|
||||
/// </summary>
|
||||
PolyLine = 7,
|
||||
/// <summary>
|
||||
/// A highlight for text or content with associated annotation texyt.
|
||||
/// </summary>
|
||||
Highlight = 8,
|
||||
/// <summary>
|
||||
/// An underline under text with associated annotation text.
|
||||
/// </summary>
|
||||
Underline = 9,
|
||||
/// <summary>
|
||||
/// A jagged squiggly line under text with associated annotation text.
|
||||
/// </summary>
|
||||
Squiggly = 10,
|
||||
/// <summary>
|
||||
/// A strikeout through some text with associated annotation text.
|
||||
/// </summary>
|
||||
StrikeOut = 11,
|
||||
/// <summary>
|
||||
/// Text or graphics intended to display as if inserted by a rubber stamp.
|
||||
/// </summary>
|
||||
Stamp = 12,
|
||||
/// <summary>
|
||||
/// A visual symbol indicating the presence of text edits.
|
||||
/// </summary>
|
||||
Caret = 13,
|
||||
/// <summary>
|
||||
/// A freehand 'scribble' formed by one or more paths.
|
||||
/// </summary>
|
||||
Ink = 14,
|
||||
/// <summary>
|
||||
/// Displays text in a pop-up window for entry or editing.
|
||||
/// </summary>
|
||||
Popup = 15,
|
||||
/// <summary>
|
||||
/// A file.
|
||||
/// </summary>
|
||||
FileAttachment = 16,
|
||||
/// <summary>
|
||||
/// A sound to be played through speakers.
|
||||
/// </summary>
|
||||
Sound = 17,
|
||||
/// <summary>
|
||||
/// Embeds a movie from a file in a PDF document.
|
||||
/// </summary>
|
||||
Movie = 18,
|
||||
/// <summary>
|
||||
/// Used by interactive forms to represent field appearance and manage user interactions.
|
||||
/// </summary>
|
||||
Widget = 19,
|
||||
/// <summary>
|
||||
/// Specifies a page region for media clips to be played and actions to be triggered from.
|
||||
/// </summary>
|
||||
Screen = 20,
|
||||
/// <summary>
|
||||
/// Represents a symbol used during the physical printing process to maintain output quality, e.g. color bars or cut marks.
|
||||
/// </summary>
|
||||
PrinterMark = 21,
|
||||
/// <summary>
|
||||
/// Used during the physical printing process to prevent colors mixing.
|
||||
/// </summary>
|
||||
TrapNet = 22,
|
||||
/// <summary>
|
||||
/// Adds a watermark at a fixed size and position irrespective of page size.
|
||||
/// </summary>
|
||||
Watermark = 23,
|
||||
/// <summary>
|
||||
/// Represents a 3D model/artwork, for example from CAD, in a PDF document.
|
||||
/// </summary>
|
||||
Artwork3D = 24,
|
||||
/// <summary>
|
||||
/// A custom annotation type.
|
||||
/// </summary>
|
||||
Other = 25
|
||||
}
|
||||
|
||||
internal static class AnnotationExtensions
|
||||
{
|
||||
public static AnnotationType ToAnnotationType(this NameToken name)
|
||||
{
|
||||
if (name.Data == NameToken.Text.Data)
|
||||
{
|
||||
return AnnotationType.Text;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Link.Data)
|
||||
{
|
||||
return AnnotationType.Link;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.FreeText.Data)
|
||||
{
|
||||
return AnnotationType.FreeText;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Line.Data)
|
||||
{
|
||||
return AnnotationType.Line;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Square.Data)
|
||||
{
|
||||
return AnnotationType.Square;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Circle.Data)
|
||||
{
|
||||
return AnnotationType.Circle;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Polygon.Data)
|
||||
{
|
||||
return AnnotationType.Polygon;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.PolyLine.Data)
|
||||
{
|
||||
return AnnotationType.PolyLine;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Highlight.Data)
|
||||
{
|
||||
return AnnotationType.Highlight;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Underline.Data)
|
||||
{
|
||||
return AnnotationType.Underline;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Squiggly.Data)
|
||||
{
|
||||
return AnnotationType.Squiggly;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.StrikeOut.Data)
|
||||
{
|
||||
return AnnotationType.StrikeOut;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Stamp.Data)
|
||||
{
|
||||
return AnnotationType.Stamp;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Caret.Data)
|
||||
{
|
||||
return AnnotationType.Caret;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Ink.Data)
|
||||
{
|
||||
return AnnotationType.Ink;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Popup.Data)
|
||||
{
|
||||
return AnnotationType.Popup;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.FileAttachment.Data)
|
||||
{
|
||||
return AnnotationType.FileAttachment;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Sound.Data)
|
||||
{
|
||||
return AnnotationType.Sound;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Movie.Data)
|
||||
{
|
||||
return AnnotationType.Movie;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Widget.Data)
|
||||
{
|
||||
return AnnotationType.Widget;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Screen.Data)
|
||||
{
|
||||
return AnnotationType.Screen;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.PrinterMark.Data)
|
||||
{
|
||||
return AnnotationType.PrinterMark;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.TrapNet.Data)
|
||||
{
|
||||
return AnnotationType.TrapNet;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Watermark.Data)
|
||||
{
|
||||
return AnnotationType.Watermark;
|
||||
}
|
||||
|
||||
if (name.Data == NameToken.Annotation3D.Data)
|
||||
{
|
||||
return AnnotationType.Artwork3D;
|
||||
}
|
||||
|
||||
return AnnotationType.Other;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Annotations;
|
||||
using Tokens;
|
||||
using Util;
|
||||
using Util.JetBrains.Annotations;
|
||||
using XObjects;
|
||||
@@ -12,6 +14,9 @@
|
||||
/// </summary>
|
||||
public class Page
|
||||
{
|
||||
private readonly DictionaryToken dictionary;
|
||||
private readonly AnnotationProvider annotationProvider;
|
||||
|
||||
/// <summary>
|
||||
/// The page number (starting at 1).
|
||||
/// </summary>
|
||||
@@ -54,13 +59,17 @@
|
||||
[NotNull]
|
||||
public Experimental ExperimentalAccess { get; }
|
||||
|
||||
internal Page(int number, MediaBox mediaBox, CropBox cropBox, PageContent content)
|
||||
internal Page(int number, DictionaryToken dictionary, MediaBox mediaBox, CropBox cropBox, PageContent content,
|
||||
AnnotationProvider annotationProvider)
|
||||
{
|
||||
if (number <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(number), "Page number cannot be 0 or negative.");
|
||||
}
|
||||
|
||||
this.dictionary = dictionary ?? throw new ArgumentNullException(nameof(dictionary));
|
||||
this.annotationProvider = annotationProvider ?? throw new ArgumentNullException(nameof(annotationProvider));
|
||||
|
||||
Number = number;
|
||||
MediaBox = mediaBox;
|
||||
CropBox = cropBox;
|
||||
@@ -100,6 +109,11 @@
|
||||
return (wordExtractor ?? DefaultWordExtractor.Instance).GetWords(Letters);
|
||||
}
|
||||
|
||||
internal IEnumerable<Annotation> GetAnnotations()
|
||||
{
|
||||
return annotationProvider.GetAnnotations();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to useful members which will change in future releases.
|
||||
/// </summary>
|
||||
|
@@ -104,10 +104,7 @@
|
||||
{
|
||||
var mediaBox = DirectObjectFinder.Get<ArrayToken>(token, pdfScanner);
|
||||
|
||||
pageTreeMembers.MediaBox = new MediaBox(new PdfRectangle(mediaBox.GetNumeric(0).Data,
|
||||
mediaBox.GetNumeric(1).Data,
|
||||
mediaBox.GetNumeric(2).Data,
|
||||
mediaBox.GetNumeric(3).Data));
|
||||
pageTreeMembers.MediaBox = new MediaBox(mediaBox.ToRectangle());
|
||||
}
|
||||
|
||||
if (!currentPageDictionary.TryGet(NameToken.Kids, out var kids)
|
||||
|
@@ -33,7 +33,7 @@
|
||||
|
||||
var privateDictionary = CompactFontFormatPrivateDictionary.GetDefault();
|
||||
|
||||
if (topDictionary.PrivateDictionaryLocation.HasValue)
|
||||
if (topDictionary.PrivateDictionaryLocation.HasValue && topDictionary.PrivateDictionaryLocation.Value.Size > 0)
|
||||
{
|
||||
var privateDictionaryBytes = data.SnapshotPortion(topDictionary.PrivateDictionaryLocation.Value.Offset,
|
||||
topDictionary.PrivateDictionaryLocation.Value.Size);
|
||||
|
@@ -130,12 +130,8 @@
|
||||
{
|
||||
return new PdfRectangle(0, 0, 0, 0);
|
||||
}
|
||||
var x1 = boxArray.GetNumeric(0).Data;
|
||||
var y1 = boxArray.GetNumeric(1).Data;
|
||||
var x2 = boxArray.GetNumeric(2).Data;
|
||||
var y2 = boxArray.GetNumeric(3).Data;
|
||||
|
||||
return new PdfRectangle(x1, y1, x2, y2);
|
||||
|
||||
return boxArray.ToRectangle();
|
||||
}
|
||||
|
||||
private static string GetCharSet(DictionaryToken dictionary)
|
||||
|
@@ -2,6 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Annotations;
|
||||
using Content;
|
||||
using Exceptions;
|
||||
using Filters;
|
||||
@@ -45,7 +46,7 @@
|
||||
|
||||
if (type != null && !type.Equals(NameToken.Page) && !isLenientParsing)
|
||||
{
|
||||
throw new InvalidOperationException($"Page {number} had its type was specified as {type} rather than 'Page'.");
|
||||
throw new InvalidOperationException($"Page {number} had its type specified as {type} rather than 'Page'.");
|
||||
}
|
||||
|
||||
MediaBox mediaBox = GetMediaBox(number, dictionary, pageTreeMembers, isLenientParsing);
|
||||
@@ -98,7 +99,7 @@
|
||||
content = GetContent(bytes, cropBox, userSpaceUnit, isLenientParsing);
|
||||
}
|
||||
|
||||
var page = new Page(number, mediaBox, cropBox, content);
|
||||
var page = new Page(number, dictionary, mediaBox, cropBox, content, new AnnotationProvider(pdfScanner, dictionary, isLenientParsing));
|
||||
|
||||
return page;
|
||||
}
|
||||
@@ -128,12 +129,7 @@
|
||||
CropBox cropBox;
|
||||
if (dictionary.TryGet(NameToken.CropBox, out var cropBoxObject) && cropBoxObject is ArrayToken cropBoxArray)
|
||||
{
|
||||
var x1 = cropBoxArray.GetNumeric(0).Int;
|
||||
var y1 = cropBoxArray.GetNumeric(1).Int;
|
||||
var x2 = cropBoxArray.GetNumeric(2).Int;
|
||||
var y2 = cropBoxArray.GetNumeric(3).Int;
|
||||
|
||||
cropBox = new CropBox(new PdfRectangle(x1, y1, x2, y2));
|
||||
cropBox = new CropBox(cropBoxArray.ToIntRectangle());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -148,12 +144,7 @@
|
||||
MediaBox mediaBox;
|
||||
if (dictionary.TryGet(NameToken.MediaBox, out var mediaboxObject) && mediaboxObject is ArrayToken mediaboxArray)
|
||||
{
|
||||
var x1 = mediaboxArray.GetNumeric(0).Int;
|
||||
var y1 = mediaboxArray.GetNumeric(1).Int;
|
||||
var x2 = mediaboxArray.GetNumeric(2).Int;
|
||||
var y2 = mediaboxArray.GetNumeric(3).Int;
|
||||
|
||||
mediaBox = new MediaBox(new PdfRectangle(x1, y1, x2, y2));
|
||||
mediaBox = new MediaBox(mediaboxArray.ToIntRectangle());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -23,6 +23,7 @@
|
||||
public static readonly NameToken Alt = new NameToken("Alt");
|
||||
public static readonly NameToken Alpha = new NameToken("Alpha");
|
||||
public static readonly NameToken Alternate = new NameToken("Alternate");
|
||||
public static readonly NameToken Annotation3D = new NameToken("3D");
|
||||
public static readonly NameToken Annot = new NameToken("Annot");
|
||||
public static readonly NameToken Annots = new NameToken("Annots");
|
||||
public static readonly NameToken AntiAlias = new NameToken("AntiAlias");
|
||||
@@ -82,6 +83,7 @@
|
||||
public static readonly NameToken Calrgb = new NameToken("CalRGB");
|
||||
public static readonly NameToken Cap = new NameToken("Cap");
|
||||
public static readonly NameToken CapHeight = new NameToken("CapHeight");
|
||||
public static readonly NameToken Caret = new NameToken("Caret");
|
||||
public static readonly NameToken Catalog = new NameToken("Catalog");
|
||||
public static readonly NameToken CcittfaxDecode = new NameToken("CCITTFaxDecode");
|
||||
public static readonly NameToken CcittfaxDecodeAbbreviation = new NameToken("CCF");
|
||||
@@ -98,6 +100,7 @@
|
||||
public static readonly NameToken CidToGidMap = new NameToken("CIDToGIDMap");
|
||||
public static readonly NameToken CidSet = new NameToken("CIDSet");
|
||||
public static readonly NameToken CidSystemInfo = new NameToken("CIDSystemInfo");
|
||||
public static readonly NameToken Circle = new NameToken("Circle");
|
||||
public static readonly NameToken Cl = new NameToken("CL");
|
||||
public static readonly NameToken ClrF = new NameToken("ClrF");
|
||||
public static readonly NameToken ClrFf = new NameToken("ClrFf");
|
||||
@@ -203,6 +206,7 @@
|
||||
public static readonly NameToken Fdf = new NameToken("FDF");
|
||||
public static readonly NameToken Ff = new NameToken("Ff");
|
||||
public static readonly NameToken Fields = new NameToken("Fields");
|
||||
public static readonly NameToken FileAttachment = new NameToken("FileAttachment");
|
||||
public static readonly NameToken Filespec = new NameToken("Filespec");
|
||||
public static readonly NameToken Filter = new NameToken("Filter");
|
||||
public static readonly NameToken First = new NameToken("First");
|
||||
@@ -226,6 +230,7 @@
|
||||
public static readonly NameToken Form = new NameToken("Form");
|
||||
public static readonly NameToken Formtype = new NameToken("FormType");
|
||||
public static readonly NameToken Frm = new NameToken("FRM");
|
||||
public static readonly NameToken FreeText = new NameToken("FreeText");
|
||||
public static readonly NameToken Ft = new NameToken("FT");
|
||||
public static readonly NameToken Function = new NameToken("Function");
|
||||
public static readonly NameToken FunctionType = new NameToken("FunctionType");
|
||||
@@ -242,6 +247,7 @@
|
||||
public static readonly NameToken HideMenubar = new NameToken("HideMenubar");
|
||||
public static readonly NameToken HideToolbar = new NameToken("HideToolbar");
|
||||
public static readonly NameToken HideWindowui = new NameToken("HideWindowUI");
|
||||
public static readonly NameToken Highlight = new NameToken("Highlight");
|
||||
// I
|
||||
public static readonly NameToken I = new NameToken("I");
|
||||
public static readonly NameToken Ic = new NameToken("IC");
|
||||
@@ -258,6 +264,7 @@
|
||||
public static readonly NameToken Index = new NameToken("Index");
|
||||
public static readonly NameToken Indexed = new NameToken("Indexed");
|
||||
public static readonly NameToken Info = new NameToken("Info");
|
||||
public static readonly NameToken Ink = new NameToken("Ink");
|
||||
public static readonly NameToken Inklist = new NameToken("InkList");
|
||||
public static readonly NameToken Interpolate = new NameToken("Interpolate");
|
||||
public static readonly NameToken It = new NameToken("IT");
|
||||
@@ -288,6 +295,8 @@
|
||||
public static readonly NameToken Length2 = new NameToken("Length2");
|
||||
public static readonly NameToken Lighten = new NameToken("Lighten");
|
||||
public static readonly NameToken Limits = new NameToken("Limits");
|
||||
public static readonly NameToken Line = new NameToken("Line");
|
||||
public static readonly NameToken Link = new NameToken("Link");
|
||||
public static readonly NameToken Lj = new NameToken("LJ");
|
||||
public static readonly NameToken Ll = new NameToken("LL");
|
||||
public static readonly NameToken Lle = new NameToken("LLE");
|
||||
@@ -317,6 +326,7 @@
|
||||
public static readonly NameToken Ml = new NameToken("ML");
|
||||
public static readonly NameToken MmType1 = new NameToken("MMType1");
|
||||
public static readonly NameToken ModDate = new NameToken("ModDate");
|
||||
public static readonly NameToken Movie = new NameToken("Movie");
|
||||
public static readonly NameToken Multiply = new NameToken("Multiply");
|
||||
// N
|
||||
public static readonly NameToken N = new NameToken("N");
|
||||
@@ -384,12 +394,16 @@
|
||||
public static readonly NameToken PdfDocEncoding = new NameToken("PDFDocEncoding");
|
||||
public static readonly NameToken Perms = new NameToken("Perms");
|
||||
public static readonly NameToken Pg = new NameToken("Pg");
|
||||
public static readonly NameToken Polygon = new NameToken("Polygon");
|
||||
public static readonly NameToken PolyLine = new NameToken("PolyLine");
|
||||
public static readonly NameToken Popup = new NameToken("Popup");
|
||||
public static readonly NameToken PreRelease = new NameToken("PreRelease");
|
||||
public static readonly NameToken Predictor = new NameToken("Predictor");
|
||||
public static readonly NameToken Prev = new NameToken("Prev");
|
||||
public static readonly NameToken PrintArea = new NameToken("PrintArea");
|
||||
public static readonly NameToken PrintClip = new NameToken("PrintClip");
|
||||
public static readonly NameToken PrintScaling = new NameToken("PrintScaling");
|
||||
public static readonly NameToken PrinterMark = new NameToken("PrinterMark");
|
||||
public static readonly NameToken ProcSet = new NameToken("ProcSet");
|
||||
public static readonly NameToken Process = new NameToken("Process");
|
||||
public static readonly NameToken Producer = new NameToken("Producer");
|
||||
@@ -440,8 +454,11 @@
|
||||
public static readonly NameToken Smask = new NameToken("SMask");
|
||||
public static readonly NameToken SoftLight = new NameToken("SoftLight");
|
||||
public static readonly NameToken Sound = new NameToken("Sound");
|
||||
public static readonly NameToken Square = new NameToken("Square");
|
||||
public static readonly NameToken Squiggly = new NameToken("Squiggly");
|
||||
public static readonly NameToken Ss = new NameToken("SS");
|
||||
public static readonly NameToken St = new NameToken("St");
|
||||
public static readonly NameToken Stamp = new NameToken("Stamp");
|
||||
public static readonly NameToken StandardEncoding = new NameToken("StandardEncoding");
|
||||
public static readonly NameToken State = new NameToken("State");
|
||||
public static readonly NameToken StateModel = new NameToken("StateModel");
|
||||
@@ -451,6 +468,7 @@
|
||||
public static readonly NameToken StemV = new NameToken("StemV");
|
||||
public static readonly NameToken StmF = new NameToken("StmF");
|
||||
public static readonly NameToken StrF = new NameToken("StrF");
|
||||
public static readonly NameToken StrikeOut = new NameToken("StrikeOut");
|
||||
public static readonly NameToken StructParent = new NameToken("StructParent");
|
||||
public static readonly NameToken StructParents = new NameToken("StructParents");
|
||||
public static readonly NameToken StructTreeRoot = new NameToken("StructTreeRoot");
|
||||
@@ -468,6 +486,7 @@
|
||||
public static readonly NameToken T = new NameToken("T");
|
||||
public static readonly NameToken Target = new NameToken("Target");
|
||||
public static readonly NameToken Templates = new NameToken("Templates");
|
||||
public static readonly NameToken Text = new NameToken("Text");
|
||||
public static readonly NameToken Threads = new NameToken("Threads");
|
||||
public static readonly NameToken Thumb = new NameToken("Thumb");
|
||||
public static readonly NameToken Ti = new NameToken("TI");
|
||||
@@ -482,6 +501,7 @@
|
||||
public static readonly NameToken Trapped = new NameToken("Trapped");
|
||||
public static readonly NameToken Trans = new NameToken("Trans");
|
||||
public static readonly NameToken Transparency = new NameToken("Transparency");
|
||||
public static readonly NameToken TrapNet = new NameToken("TrapNet");
|
||||
public static readonly NameToken Tref = new NameToken("TRef");
|
||||
public static readonly NameToken TrimBox = new NameToken("TrimBox");
|
||||
public static readonly NameToken TrueType = new NameToken("TrueType");
|
||||
@@ -498,6 +518,7 @@
|
||||
public static readonly NameToken U = new NameToken("U");
|
||||
public static readonly NameToken Ue = new NameToken("UE");
|
||||
public static readonly NameToken Uf = new NameToken("UF");
|
||||
public static readonly NameToken Underline = new NameToken("Underline");
|
||||
public static readonly NameToken Unchanged = new NameToken("Unchanged");
|
||||
public static readonly NameToken Unix = new NameToken("Unix");
|
||||
public static readonly NameToken Uri = new NameToken("URI");
|
||||
@@ -516,6 +537,7 @@
|
||||
// W
|
||||
public static readonly NameToken W = new NameToken("W");
|
||||
public static readonly NameToken W2 = new NameToken("W2");
|
||||
public static readonly NameToken Watermark = new NameToken("Watermark");
|
||||
public static readonly NameToken WhitePoint = new NameToken("WhitePoint");
|
||||
public static readonly NameToken Widget = new NameToken("Widget");
|
||||
public static readonly NameToken Width = new NameToken("Width");
|
||||
|
@@ -2,6 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
using Exceptions;
|
||||
using Geometry;
|
||||
using JetBrains.Annotations;
|
||||
using Tokens;
|
||||
|
||||
@@ -80,7 +81,7 @@
|
||||
|
||||
if (index < 0 || index >= array.Data.Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new ArgumentOutOfRangeException($"Cannot index into array at index {index}. Array was: {array}.");
|
||||
}
|
||||
|
||||
if (array.Data[index] is NumericToken numeric)
|
||||
@@ -88,7 +89,43 @@
|
||||
return numeric;
|
||||
}
|
||||
|
||||
throw new PdfDocumentFormatException();
|
||||
throw new PdfDocumentFormatException($"The array did not contain a number at index {index}. Array was: {array}.");
|
||||
}
|
||||
|
||||
public static PdfRectangle ToRectangle(this ArrayToken array)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(array));
|
||||
}
|
||||
|
||||
if (array.Data.Count != 4)
|
||||
{
|
||||
throw new PdfDocumentFormatException($"Cannot convert array to rectangle, expected 4 values instead got: {array}.");
|
||||
}
|
||||
|
||||
return new PdfRectangle(array.GetNumeric(0).Data,
|
||||
array.GetNumeric(1).Data,
|
||||
array.GetNumeric(2).Data,
|
||||
array.GetNumeric(3).Data);
|
||||
}
|
||||
|
||||
public static PdfRectangle ToIntRectangle(this ArrayToken array)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(array));
|
||||
}
|
||||
|
||||
if (array.Data.Count != 4)
|
||||
{
|
||||
throw new PdfDocumentFormatException($"Cannot convert array to rectangle, expected 4 values instead got: {array}.");
|
||||
}
|
||||
|
||||
return new PdfRectangle(array.GetNumeric(0).Int,
|
||||
array.GetNumeric(1).Int,
|
||||
array.GetNumeric(2).Int,
|
||||
array.GetNumeric(3).Int);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user