mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-11-24 16:53:20 +08:00
support looking up in reply to value for annotation #362
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
namespace UglyToad.PdfPig.Tests.Integration;
|
||||
|
||||
using Annotations;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
public class AnnotationReplyToTests
|
||||
{
|
||||
private static string GetFilename()
|
||||
{
|
||||
return IntegrationHelpers.GetDocumentPath("annotation-comments.pdf");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasCorrectNumberOfAnnotations()
|
||||
{
|
||||
using var document = PdfDocument.Open(GetFilename());
|
||||
|
||||
var page = document.GetPage(1);
|
||||
|
||||
var annotations = page.ExperimentalAccess.GetAnnotations().ToList();
|
||||
|
||||
Assert.Equal(4, annotations.Count);
|
||||
|
||||
Assert.Equal(AnnotationType.Text, annotations[0].Type);
|
||||
Assert.Equal(AnnotationType.Popup, annotations[1].Type);
|
||||
Assert.Equal(AnnotationType.Text, annotations[2].Type);
|
||||
Assert.Equal(AnnotationType.Popup, annotations[3].Type);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SecondTextReplyToFirst()
|
||||
{
|
||||
using var document = PdfDocument.Open(GetFilename());
|
||||
|
||||
var page = document.GetPage(1);
|
||||
|
||||
var annotations = page.ExperimentalAccess.GetAnnotations().ToList();
|
||||
|
||||
Assert.Equal(annotations[0], annotations[2].InReplyTo);
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -290,6 +290,7 @@
|
||||
public static readonly NameToken Inklist = new NameToken("InkList");
|
||||
public static readonly NameToken Intent = new NameToken("Intent");
|
||||
public static readonly NameToken Interpolate = new NameToken("Interpolate");
|
||||
public static readonly NameToken Irt = new NameToken("IRT");
|
||||
public static readonly NameToken It = new NameToken("IT");
|
||||
public static readonly NameToken ItalicAngle = new NameToken("ItalicAngle");
|
||||
// J
|
||||
|
||||
@@ -88,15 +88,30 @@
|
||||
/// </summary>
|
||||
public bool HasDownAppearance => downAppearanceStream != null;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Annotation"/> this annotation was in reply to. Can be <see langword="null" />
|
||||
/// </summary>
|
||||
public Annotation InReplyTo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="Annotation"/>.
|
||||
/// </summary>
|
||||
public Annotation(DictionaryToken annotationDictionary, AnnotationType type, PdfRectangle rectangle,
|
||||
string content, string name, string modifiedDate,
|
||||
AnnotationFlags flags, AnnotationBorder border, IReadOnlyList<QuadPointsQuadrilateral> quadPoints,
|
||||
public Annotation(
|
||||
DictionaryToken annotationDictionary,
|
||||
AnnotationType type,
|
||||
PdfRectangle rectangle,
|
||||
string content,
|
||||
string name,
|
||||
string modifiedDate,
|
||||
AnnotationFlags flags,
|
||||
AnnotationBorder border,
|
||||
IReadOnlyList<QuadPointsQuadrilateral> quadPoints,
|
||||
PdfAction action,
|
||||
AppearanceStream normalAppearanceStream, AppearanceStream rollOverAppearanceStream,
|
||||
AppearanceStream downAppearanceStream, string appearanceState)
|
||||
AppearanceStream normalAppearanceStream,
|
||||
AppearanceStream rollOverAppearanceStream,
|
||||
AppearanceStream downAppearanceStream,
|
||||
string appearanceState,
|
||||
Annotation inReplyTo)
|
||||
{
|
||||
AnnotationDictionary = annotationDictionary ?? throw new ArgumentNullException(nameof(annotationDictionary));
|
||||
Type = type;
|
||||
@@ -112,6 +127,7 @@
|
||||
this.rollOverAppearanceStream = rollOverAppearanceStream;
|
||||
this.downAppearanceStream = downAppearanceStream;
|
||||
this.appearanceState = appearanceState;
|
||||
InReplyTo = inReplyTo;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
public IEnumerable<Annotation> GetAnnotations()
|
||||
{
|
||||
var lookupAnnotations = new Dictionary<IndirectReference, Annotation>();
|
||||
|
||||
if (!pageDictionary.TryGet(NameToken.Annots, tokenScanner, out ArrayToken annotationsArray))
|
||||
{
|
||||
yield break;
|
||||
@@ -45,6 +47,13 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
Annotation replyTo = null;
|
||||
if (annotationDictionary.TryGet(NameToken.Irt, out IndirectReferenceToken referencedAnnotation)
|
||||
&& lookupAnnotations.TryGetValue(referencedAnnotation.Data, out var linkedAnnotation))
|
||||
{
|
||||
replyTo = linkedAnnotation;
|
||||
}
|
||||
|
||||
var type = annotationDictionary.Get<NameToken>(NameToken.Subtype, tokenScanner);
|
||||
var annotationType = type.ToAnnotationType();
|
||||
var action = GetAction(annotationDictionary);
|
||||
@@ -136,9 +145,29 @@
|
||||
appearanceState = appearanceStateToken.Data;
|
||||
}
|
||||
|
||||
yield return new Annotation(annotationDictionary, annotationType, rectangle,
|
||||
contents, name, modifiedDate, flags, border, quadPointRectangles, action,
|
||||
normalAppearanceStream, rollOverAppearanceStream, downAppearanceStream, appearanceState);
|
||||
var annotation = new Annotation(
|
||||
annotationDictionary,
|
||||
annotationType,
|
||||
rectangle,
|
||||
contents,
|
||||
name,
|
||||
modifiedDate,
|
||||
flags,
|
||||
border,
|
||||
quadPointRectangles,
|
||||
action,
|
||||
normalAppearanceStream,
|
||||
rollOverAppearanceStream,
|
||||
downAppearanceStream,
|
||||
appearanceState,
|
||||
replyTo);
|
||||
|
||||
if (token is IndirectReferenceToken indirectReference)
|
||||
{
|
||||
lookupAnnotations[indirectReference.Data] = annotation;
|
||||
}
|
||||
|
||||
yield return annotation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user