account for skipmissingfonts in positioned text #637

This commit is contained in:
Eliot Jones 2023-06-04 11:47:30 +01:00
parent 6daa2ec192
commit 9d2b3f914d
2 changed files with 115 additions and 101 deletions

View File

@ -1,106 +1,106 @@
namespace UglyToad.PdfPig.Content
{
using Core;
using Outline;
using System;
using System.Collections.Generic;
using Tokenization.Scanner;
using Tokens;
using Util;
internal class Pages
{
private readonly IPageFactory pageFactory;
private readonly IPdfTokenScanner pdfScanner;
private readonly Dictionary<int, PageTreeNode> pagesByNumber;
namespace UglyToad.PdfPig.Content
{
using Core;
using Outline;
using System;
using System.Collections.Generic;
using Tokenization.Scanner;
using Tokens;
using Util;
internal class Pages
{
private readonly IPageFactory pageFactory;
private readonly IPdfTokenScanner pdfScanner;
private readonly Dictionary<int, PageTreeNode> pagesByNumber;
public int Count => pagesByNumber.Count;
/// <summary>
/// The page tree for this document containing all pages, page numbers and their dictionaries.
/// </summary>
public PageTreeNode PageTree { get; }
internal Pages(IPageFactory pageFactory, IPdfTokenScanner pdfScanner, PageTreeNode pageTree, Dictionary<int, PageTreeNode> pagesByNumber)
{
this.pageFactory = pageFactory ?? throw new ArgumentNullException(nameof(pageFactory));
this.pdfScanner = pdfScanner ?? throw new ArgumentNullException(nameof(pdfScanner));
this.pagesByNumber = pagesByNumber;
PageTree = pageTree;
}
internal Page GetPage(int pageNumber, NamedDestinations namedDestinations, InternalParsingOptions parsingOptions)
{
if (pageNumber <= 0 || pageNumber > Count)
{
parsingOptions.Logger.Error($"Page {pageNumber} requested but is out of range.");
throw new ArgumentOutOfRangeException(nameof(pageNumber),
$"Page number {pageNumber} invalid, must be between 1 and {Count}.");
}
var pageNode = GetPageNode(pageNumber);
var pageStack = new Stack<PageTreeNode>();
var currentNode = pageNode;
while (currentNode != null)
{
pageStack.Push(currentNode);
currentNode = currentNode.Parent;
}
var pageTreeMembers = new PageTreeMembers();
while (pageStack.Count > 0)
{
currentNode = pageStack.Pop();
if (currentNode.NodeDictionary.TryGet(NameToken.Resources, pdfScanner, out DictionaryToken resourcesDictionary))
{
pageTreeMembers.ParentResources.Enqueue(resourcesDictionary);
}
if (currentNode.NodeDictionary.TryGet(NameToken.MediaBox, pdfScanner, out ArrayToken mediaBox))
{
pageTreeMembers.MediaBox = new MediaBox(mediaBox.ToRectangle(pdfScanner));
}
if (currentNode.NodeDictionary.TryGet(NameToken.Rotate, pdfScanner, out NumericToken rotateToken))
{
pageTreeMembers.Rotation = rotateToken.Int;
}
/// </summary>
public PageTreeNode PageTree { get; }
internal Pages(IPageFactory pageFactory, IPdfTokenScanner pdfScanner, PageTreeNode pageTree, Dictionary<int, PageTreeNode> pagesByNumber)
{
this.pageFactory = pageFactory ?? throw new ArgumentNullException(nameof(pageFactory));
this.pdfScanner = pdfScanner ?? throw new ArgumentNullException(nameof(pdfScanner));
this.pagesByNumber = pagesByNumber;
PageTree = pageTree;
}
internal Page GetPage(int pageNumber, NamedDestinations namedDestinations, InternalParsingOptions parsingOptions)
{
if (pageNumber <= 0 || pageNumber > Count)
{
parsingOptions.Logger.Error($"Page {pageNumber} requested but is out of range.");
throw new ArgumentOutOfRangeException(nameof(pageNumber),
$"Page number {pageNumber} invalid, must be between 1 and {Count}.");
}
var page = pageFactory.Create(
pageNumber,
pageNode.NodeDictionary,
pageTreeMembers,
namedDestinations,
parsingOptions);
return page;
}
internal PageTreeNode GetPageNode(int pageNumber)
{
if (!pagesByNumber.TryGetValue(pageNumber, out var node))
{
throw new InvalidOperationException($"Could not find page node by number for: {pageNumber}.");
}
return node;
}
internal PageTreeNode GetPageByReference(IndirectReference reference)
{
foreach (var page in pagesByNumber)
{
if (page.Value.Reference.Equals(reference))
{
return page.Value;
}
}
return null;
}
}
}
var pageNode = GetPageNode(pageNumber);
var pageStack = new Stack<PageTreeNode>();
var currentNode = pageNode;
while (currentNode != null)
{
pageStack.Push(currentNode);
currentNode = currentNode.Parent;
}
var pageTreeMembers = new PageTreeMembers();
while (pageStack.Count > 0)
{
currentNode = pageStack.Pop();
if (currentNode.NodeDictionary.TryGet(NameToken.Resources, pdfScanner, out DictionaryToken resourcesDictionary))
{
pageTreeMembers.ParentResources.Enqueue(resourcesDictionary);
}
if (currentNode.NodeDictionary.TryGet(NameToken.MediaBox, pdfScanner, out ArrayToken mediaBox))
{
pageTreeMembers.MediaBox = new MediaBox(mediaBox.ToRectangle(pdfScanner));
}
if (currentNode.NodeDictionary.TryGet(NameToken.Rotate, pdfScanner, out NumericToken rotateToken))
{
pageTreeMembers.Rotation = rotateToken.Int;
}
}
var page = pageFactory.Create(
pageNumber,
pageNode.NodeDictionary,
pageTreeMembers,
namedDestinations,
parsingOptions);
return page;
}
internal PageTreeNode GetPageNode(int pageNumber)
{
if (!pagesByNumber.TryGetValue(pageNumber, out var node))
{
throw new InvalidOperationException($"Could not find page node by number for: {pageNumber}.");
}
return node;
}
internal PageTreeNode GetPageByReference(IndirectReference reference)
{
foreach (var page in pagesByNumber)
{
if (page.Value.Reference.Equals(reference))
{
return page.Value;
}
}
return null;
}
}
}

View File

@ -380,6 +380,20 @@
var horizontalScaling = textState.HorizontalScaling / 100.0;
var font = resourceStore.GetFont(textState.FontName);
if (font == null)
{
if (parsingOptions.SkipMissingFonts)
{
parsingOptions.Logger.Warn($"Skipping a missing font with name {currentState.FontState.FontName} " +
$"since it is not present in the document and {nameof(InternalParsingOptions.SkipMissingFonts)} " +
"is set to true. This may result in some text being skipped and not included in the output.");
return;
}
throw new InvalidOperationException($"Could not find the font with name {currentState.FontState.FontName} in the resource store. It has not been loaded yet.");
}
var isVertical = font.IsVertical;
foreach (var token in tokens)