Fix for page object having as parent his own object

I decided to move to his own method, the part that create the page node. This allowed me to visualize better, from where I was suppose to get the correct reference.
This commit is contained in:
Inusual
2020-02-24 20:35:58 -04:00
committed by Eliot Jones
parent f485826751
commit 669742b6bd
2 changed files with 46 additions and 51 deletions

View File

@@ -14,8 +14,7 @@
var result = PdfMerger.Merge(one, two); var result = PdfMerger.Merge(one, two);
// FIX: Enable UseLenianParseOff using (var document = PdfDocument.Open(result, ParsingOptions.LenientParsingOff))
using (var document = PdfDocument.Open(result/*, ParsingOptions.LenientParsingOff */))
{ {
Assert.Equal(2, document.NumberOfPages); Assert.Equal(2, document.NumberOfPages);

View File

@@ -204,72 +204,64 @@
throw new ObjectDisposedException("Merger disposed already"); throw new ObjectDisposedException("Merger disposed already");
} }
/* var pagesReference = CopyPagesTree(newDocument.Catalog.PageTree, RootPagesIndirectReference, tokenScanner);
* I decided that I want to have an /Pages object for each document's pages. That way I avoided resource name conflict DocumentPages.Add(new IndirectReferenceToken(pagesReference.Number));
* But I guess that doesn't matter either way? So that part can be eliminated? }
*/
var pageReferences = ConstructPageReferences(newDocument.Catalog.PageTree, tokenScanner); private ObjectToken CopyPagesTree(PageTreeNode treeNode, IndirectReferenceToken treeParentReference, IPdfTokenScanner tokenScanner)
{
Debug.Assert(!treeNode.IsPage);
var currentNodeReserved = Context.ReserveNumber();
var currentNodeReference = new IndirectReferenceToken(new IndirectReference(currentNodeReserved, 0));
var pageReferences = new List<IndirectReferenceToken>();
foreach (var pageNode in treeNode.Children)
{
IndirectReference newEntry;
if (!pageNode.IsPage)
newEntry = CopyPagesTree(pageNode, currentNodeReference, tokenScanner).Number;
else
newEntry = CopyPageNode(pageNode, currentNodeReference, tokenScanner).Number;
pageReferences.Add(new IndirectReferenceToken(newEntry));
}
var pagesDictionary = new DictionaryToken(new Dictionary<NameToken, IToken> var pagesDictionary = new DictionaryToken(new Dictionary<NameToken, IToken>
{ {
{ NameToken.Type, NameToken.Pages }, { NameToken.Type, NameToken.Pages },
{ NameToken.Kids, new ArrayToken(pageReferences) }, { NameToken.Kids, new ArrayToken(pageReferences) },
{ NameToken.Count, new NumericToken(pageReferences.Count) }, { NameToken.Count, new NumericToken(pageReferences.Count) },
{ NameToken.Parent, RootPagesIndirectReference } { NameToken.Parent, treeParentReference }
}); });
var pagesRef = Context.WriteObject(Memory, pagesDictionary); return Context.WriteObject(Memory, pagesDictionary, currentNodeReserved);
DocumentPages.Add(new IndirectReferenceToken(pagesRef.Number));
} }
private IReadOnlyList<IndirectReferenceToken> ConstructPageReferences(PageTreeNode treeNode, IPdfTokenScanner tokenScanner) private ObjectToken CopyPageNode(PageTreeNode pageNode, IndirectReferenceToken parentPagesObject, IPdfTokenScanner tokenScanner)
{ {
var reserved = Context.ReserveNumber(); Debug.Assert(pageNode.IsPage);
var parentIndirect = new IndirectReferenceToken(new IndirectReference(reserved, 0));
var pageReferences = new List<IndirectReferenceToken>(); var pageDictionary = new Dictionary<NameToken, IToken>
foreach (var pageNode in treeNode.Children)
{ {
if (!pageNode.IsPage) {NameToken.Parent, parentPagesObject},
{ };
var nestedPageReferences = ConstructPageReferences(pageNode, tokenScanner);
var pagesDictionary = new DictionaryToken(new Dictionary<NameToken, IToken>
{
{ NameToken.Type, NameToken.Pages },
{ NameToken.Kids, new ArrayToken(nestedPageReferences) },
{ NameToken.Count, new NumericToken(nestedPageReferences.Count) },
{ NameToken.Parent, parentIndirect }
});
var pagesRef = Context.WriteObject(Memory, pagesDictionary); foreach (var setPair in pageNode.NodeDictionary.Data)
pageReferences.Add(new IndirectReferenceToken(pagesRef.Number)); {
var name = setPair.Key;
var token = setPair.Value;
if (name == NameToken.Parent)
{
// Skip Parent token, since we have to reassign it
continue; continue;
} }
var pageDictionary = new Dictionary<NameToken, IToken> pageDictionary.Add(NameToken.Create(name), CopyToken(token, tokenScanner));
{
{NameToken.Parent, parentIndirect},
};
foreach(var setPair in pageNode.NodeDictionary.Data)
{
var name = setPair.Key;
var token = setPair.Value;
if (name == NameToken.Parent)
{
// Skip Parent token, since we have to reassign it
continue;
}
pageDictionary.Add(NameToken.Create(name), CopyToken(token, tokenScanner));
}
var pageRef = Context.WriteObject(Memory, new DictionaryToken(pageDictionary), reserved);
pageReferences.Add(new IndirectReferenceToken(pageRef.Number));
} }
return pageReferences; return Context.WriteObject(Memory, new DictionaryToken(pageDictionary));
} }
private IToken CopyToken(IToken tokenToCopy, IPdfTokenScanner tokenScanner) private IToken CopyToken(IToken tokenToCopy, IPdfTokenScanner tokenScanner)
@@ -299,7 +291,7 @@
else if (tokenToCopy is IndirectReferenceToken referenceToken) else if (tokenToCopy is IndirectReferenceToken referenceToken)
{ {
var tokenObject = DirectObjectFinder.Get<IToken>(referenceToken.Data, tokenScanner); var tokenObject = DirectObjectFinder.Get<IToken>(referenceToken.Data, tokenScanner);
// Is this even a allowed? // Is this even a allowed?
Debug.Assert(!(tokenObject is IndirectReferenceToken)); Debug.Assert(!(tokenObject is IndirectReferenceToken));
@@ -307,7 +299,11 @@
var objToken = Context.WriteObject(Memory, newToken); var objToken = Context.WriteObject(Memory, newToken);
return new IndirectReferenceToken(objToken.Number); return new IndirectReferenceToken(objToken.Number);
} }
else else if (tokenToCopy is StreamToken streamToken)
{
return streamToken;
}
else // Non Complex Token - BooleanToken, NumericToken, NameToken, Etc...
{ {
// TODO: Should we do a deep copy of the token? // TODO: Should we do a deep copy of the token?
return tokenToCopy; return tokenToCopy;