make bookmarknode immutable and use scanner when retrieving bookmarks

This commit is contained in:
Eliot Jones
2019-12-05 12:03:30 +00:00
parent 928347bcce
commit ecf0b8743b
5 changed files with 684 additions and 383 deletions

View File

@@ -40,5 +40,15 @@
} }
} }
} }
[Fact]
public void CanGetBookmarks()
{
using (var document = PdfDocument.Open(GetFilename()))
{
var foundBookmarks = document.TryGetBookmarks(out var bookmarks);
Assert.True(foundBookmarks);
}
}
} }
} }

View File

@@ -3,6 +3,8 @@ using UglyToad.PdfPig.Geometry;
namespace UglyToad.PdfPig.Outline namespace UglyToad.PdfPig.Outline
{ {
using System;
/// <summary> /// <summary>
/// A node in the <see cref="Bookmarks"/> of a PDF document. /// A node in the <see cref="Bookmarks"/> of a PDF document.
/// </summary> /// </summary>
@@ -11,55 +13,60 @@ namespace UglyToad.PdfPig.Outline
/// <summary> /// <summary>
/// The text displayed for this node. /// The text displayed for this node.
/// </summary> /// </summary>
public string Title { get; internal set; } public string Title { get; }
/// <summary> /// <summary>
/// The bookmark's coordinates in the pdf page. /// The bookmark's coordinates in the pdf page.
/// </summary> /// </summary>
public PdfPoint TopLeft { get; internal set; } public PdfPoint TopLeft { get; }
/// <summary> /// <summary>
/// The bookmark's bounding box in the pdf page. /// The bookmark's bounding box in the pdf page.
/// </summary> /// </summary>
public PdfRectangle BoundingBox { get; internal set; } public PdfRectangle BoundingBox { get; }
/// <summary> /// <summary>
/// The node's hierarchical level. /// The node's hierarchical level.
/// </summary> /// </summary>
public int Level { get; internal set; } public int Level { get; }
/// <summary> /// <summary>
/// The page's number where the bookmark is located. /// The page number where the bookmark is located.
/// </summary> /// </summary>
public int PageNumber { get; internal set; } public int PageNumber { get; }
/// <summary> /// <summary>
/// The link to an external source. /// The link to an external source.
/// </summary> /// </summary>
public string ExternalLink { get; internal set; } public string ExternalLink { get; }
/// <summary> /// <summary>
/// True if bookmark refers to an external source. /// True if bookmark refers to an external source.
/// </summary> /// </summary>
public bool IsExternal { get; internal set; } public bool IsExternal { get; }
/// <summary> /// <summary>
/// The bookmark's sub-bookmark. /// The bookmark's sub-bookmark.
/// </summary> /// </summary>
public List<BookmarkNode> Children { get; internal set; } public IReadOnlyList<BookmarkNode> Children { get; }
/// <summary> /// <inheritdoc />
/// Create a new instance of BookmarkNode. public BookmarkNode(string title, PdfPoint topLeft, PdfRectangle boundingBox, int level, int pageNumber,
/// </summary> string externalLink,
public BookmarkNode() bool isExternal,
IReadOnlyList<BookmarkNode> children)
{ {
Title = string.Empty; Title = title;
Children = new List<BookmarkNode>(); TopLeft = topLeft;
BoundingBox = boundingBox;
Level = level;
PageNumber = pageNumber;
ExternalLink = externalLink;
IsExternal = isExternal;
Children = children ?? throw new ArgumentNullException(nameof(children));
} }
/// <summary> /// <inheritdoc />
///
/// </summary>
public override string ToString() public override string ToString()
{ {
return "page #" + PageNumber + ", " + Level + ", " + Title; return "page #" + PageNumber + ", " + Level + ", " + Title;

File diff suppressed because it is too large Load Diff

View File

@@ -21,6 +21,7 @@
using Graphics; using Graphics;
using IO; using IO;
using Logging; using Logging;
using Outline;
using Parts; using Parts;
using Parts.CrossReference; using Parts.CrossReference;
using Tokenization.Scanner; using Tokenization.Scanner;
@@ -136,12 +137,14 @@
var caching = new ParsingCachingProviders(bruteForceSearcher, resourceContainer); var caching = new ParsingCachingProviders(bruteForceSearcher, resourceContainer);
var acroFormFactory = new AcroFormFactory(pdfScanner, filterProvider); var acroFormFactory = new AcroFormFactory(pdfScanner, filterProvider);
var bookmarksProvider = new BookmarksProvider(log, pdfScanner, isLenientParsing);
return new PdfDocument(log, inputBytes, version, crossReferenceTable, isLenientParsing, caching, pageFactory, catalog, information, return new PdfDocument(log, inputBytes, version, crossReferenceTable, isLenientParsing, caching, pageFactory, catalog, information,
encryptionDictionary, encryptionDictionary,
pdfScanner, pdfScanner,
filterProvider, filterProvider,
acroFormFactory); acroFormFactory,
bookmarksProvider);
} }
private static (IndirectReference, DictionaryToken) ParseTrailer(CrossReferenceTable crossReferenceTable, bool isLenientParsing, IPdfTokenScanner pdfTokenScanner, private static (IndirectReference, DictionaryToken) ParseTrailer(CrossReferenceTable crossReferenceTable, bool isLenientParsing, IPdfTokenScanner pdfTokenScanner,

View File

@@ -14,7 +14,7 @@
using Parser; using Parser;
using Tokenization.Scanner; using Tokenization.Scanner;
using Tokens; using Tokens;
using UglyToad.PdfPig.Outline; using Outline;
using Util.JetBrains.Annotations; using Util.JetBrains.Annotations;
/// <inheritdoc /> /// <inheritdoc />
@@ -45,6 +45,7 @@
private readonly IPdfTokenScanner pdfScanner; private readonly IPdfTokenScanner pdfScanner;
private readonly IFilterProvider filterProvider; private readonly IFilterProvider filterProvider;
private readonly BookmarksProvider bookmarksProvider;
[NotNull] [NotNull]
private readonly Pages pages; private readonly Pages pages;
@@ -88,7 +89,8 @@
EncryptionDictionary encryptionDictionary, EncryptionDictionary encryptionDictionary,
IPdfTokenScanner pdfScanner, IPdfTokenScanner pdfScanner,
IFilterProvider filterProvider, IFilterProvider filterProvider,
AcroFormFactory acroFormFactory) AcroFormFactory acroFormFactory,
BookmarksProvider bookmarksProvider)
{ {
this.log = log; this.log = log;
this.inputBytes = inputBytes; this.inputBytes = inputBytes;
@@ -98,6 +100,7 @@
this.encryptionDictionary = encryptionDictionary; this.encryptionDictionary = encryptionDictionary;
this.pdfScanner = pdfScanner ?? throw new ArgumentNullException(nameof(pdfScanner)); this.pdfScanner = pdfScanner ?? throw new ArgumentNullException(nameof(pdfScanner));
this.filterProvider = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider)); this.filterProvider = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
this.bookmarksProvider = bookmarksProvider ?? throw new ArgumentNullException(nameof(bookmarksProvider));
Information = information ?? throw new ArgumentNullException(nameof(information)); Information = information ?? throw new ArgumentNullException(nameof(information));
pages = new Pages(catalog, pageFactory, isLenientParsing, pdfScanner); pages = new Pages(catalog, pageFactory, isLenientParsing, pdfScanner);
Structure = new Structure(catalog, crossReferenceTable, pdfScanner); Structure = new Structure(catalog, crossReferenceTable, pdfScanner);
@@ -209,8 +212,7 @@
throw new ObjectDisposedException("Cannot access the bookmarks after the document is disposed."); throw new ObjectDisposedException("Cannot access the bookmarks after the document is disposed.");
} }
var bookmarksProvider = new BookmarksProvider(this.log, this.Structure); bookmarks = bookmarksProvider.GetBookmarks(Structure.Catalog);
bookmarks = bookmarksProvider.GetBookmarks();
if (bookmarks != null) return true; if (bookmarks != null) return true;
return false; return false;
} }