Fix page number order.

For case when root nod has reference to page the order will be incorrect.
The case if root node has reference
[2 0 R 3 0 R 10 0 R]
Where 2 0 R is intermediate node containing page 1,2,3

Where 3 0 R is intermediate node containing page 4,5,6
Where 10 0 R is page 7

without that fix 7 page will in array as page 1
This commit is contained in:
grinay
2022-07-29 18:27:56 +08:00
parent 545d1a0793
commit 19962af011
3 changed files with 55 additions and 3 deletions

View File

@@ -32,7 +32,7 @@
/// <summary>
/// The number of this page if <see cref="IsPage"/> is <see langword="true"/>.
/// </summary>
public int? PageNumber { get; }
public int? PageNumber { get; internal set; }
/// <summary>
/// The child nodes of this node if <see cref="IsPage"/> is <see langword="false" />

View File

@@ -5,8 +5,10 @@
using Content;
using Core;
using Parts;
using System.Linq;
using Tokenization.Scanner;
using Tokens;
using Util;
internal static class CatalogFactory
{
@@ -81,6 +83,8 @@
return new PageTreeNode(nodeDictionaryInput, referenceInput, true, pageNumber.PageCount).WithChildren(EmptyArray<PageTreeNode>.Instance);
}
//If we got here, we have to iterate till we manage to exit
var toProcess =
@@ -126,8 +130,6 @@
if (isChildPage)
{
pageNumber.Increment();
var kidPageNode =
new PageTreeNode(kidDictionaryToken, kidRef.Data, true, pageNumber.PageCount).WithChildren(EmptyArray<PageTreeNode>.Instance);
current.nodeChildren.Add(kidPageNode);
@@ -152,6 +154,12 @@
action();
}
foreach (var child in firstPage.Children.ToRecursiveOrderList(x=>x.Children).Where(child => child.IsPage))
{
pageNumber.Increment();
child.PageNumber = pageNumber.PageCount;
}
return firstPage;
}

View File

@@ -0,0 +1,44 @@
namespace UglyToad.PdfPig.Util
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
internal static class EnumerableExtensions
{
public static List<T> ToRecursiveOrderList<T>(this IEnumerable<T> collection,
Expression<Func<T, IEnumerable<T>>> childCollection)
{
var resultList = new List<T>();
var currentItems = new Queue<(int Index, T Item, int Depth)>(collection.Select(i => (0, i, 0)));
var depthItemCounter = 0;
var previousItemDepth = 0;
var childProperty = (PropertyInfo)((MemberExpression)childCollection.Body).Member;
while (currentItems.Count > 0)
{
var currentItem = currentItems.Dequeue();
// Reset counter for number of items at this depth when the depth changes.
if (currentItem.Depth != previousItemDepth)
{
depthItemCounter = 0;
}
var resultIndex = currentItem.Index + depthItemCounter++;
resultList.Insert(resultIndex, currentItem.Item);
var childItems = childProperty.GetValue(currentItem.Item) as IEnumerable<T> ?? Enumerable.Empty<T>();
foreach (var childItem in childItems)
{
currentItems.Enqueue((resultIndex + 1, childItem, currentItem.Depth + 1));
}
previousItemDepth = currentItem.Depth;
}
return resultList;
}
}
}