mirror of
https://github.com/UglyToad/PdfPig.git
synced 2026-03-10 00:23:29 +08:00
writer util did not follow reference links #1032
when copying various dictionaries from a source document to the builder any indirect references in the source document would throw because the code expected the dictionary token directly. now we follow the list of indirect references until we find a non-indirect leaf token. also changes the exception type.
This commit is contained in:
@@ -831,7 +831,7 @@
|
||||
// We need to relocate the resources, and we have to make sure that none of the resources collide with
|
||||
// the already written operation's resources
|
||||
|
||||
var resources = pageDictionary.GetOrCreateDict(NameToken.Resources);
|
||||
var resources = pageDictionary.GetOrCreateDict(NameToken.Resources, srcPage.pdfScanner);
|
||||
|
||||
foreach (var set in srcResourceDictionary.Data)
|
||||
{
|
||||
@@ -858,7 +858,7 @@
|
||||
// Since we don't directly add font's to the pages resources, we have to go look at the document's font
|
||||
if (srcResourceDictionary.TryGet(NameToken.Font, srcPage.pdfScanner, out DictionaryToken? fontsDictionary))
|
||||
{
|
||||
var pageFontsDictionary = resources.GetOrCreateDict(NameToken.Font);
|
||||
var pageFontsDictionary = resources.GetOrCreateDict(NameToken.Font, srcPage.pdfScanner);
|
||||
|
||||
foreach (var fontSet in fontsDictionary.Data)
|
||||
{
|
||||
@@ -903,7 +903,7 @@
|
||||
// Since we don't directly add xobjects's to the pages resources, we have to go look at the document's xobjects
|
||||
if (srcResourceDictionary.TryGet(NameToken.Xobject, srcPage.pdfScanner, out DictionaryToken? xobjectsDictionary))
|
||||
{
|
||||
var pageXobjectsDictionary = resources.GetOrCreateDict(NameToken.Xobject);
|
||||
var pageXobjectsDictionary = resources.GetOrCreateDict(NameToken.Xobject, srcPage.pdfScanner);
|
||||
|
||||
foreach (var xobjectSet in xobjectsDictionary.Data)
|
||||
{
|
||||
@@ -945,7 +945,7 @@
|
||||
// Since we don't directly add xobjects's to the pages resources, we have to go look at the document's xobjects
|
||||
if (srcResourceDictionary.TryGet(NameToken.ExtGState, srcPage.pdfScanner, out DictionaryToken? gsDictionary))
|
||||
{
|
||||
var pageGstateDictionary = resources.GetOrCreateDict(NameToken.ExtGState);
|
||||
var pageGstateDictionary = resources.GetOrCreateDict(NameToken.ExtGState, srcPage.pdfScanner);
|
||||
|
||||
foreach (var gstate in gsDictionary.Data)
|
||||
{
|
||||
|
||||
@@ -12,13 +12,36 @@
|
||||
|
||||
internal static class WriterUtil
|
||||
{
|
||||
public static Dictionary<string, IToken> GetOrCreateDict(this Dictionary<NameToken, IToken> dict, NameToken key)
|
||||
public static Dictionary<string, IToken> GetOrCreateDict<T>(
|
||||
this Dictionary<T, IToken> dict,
|
||||
T key,
|
||||
IPdfTokenScanner? sourceScanner = null) where T : notnull
|
||||
{
|
||||
if (dict.TryGetValue(key, out var item))
|
||||
{
|
||||
if (!(item is DictionaryToken dt))
|
||||
var chainCount = 0;
|
||||
var itemChain = item;
|
||||
while (itemChain is IndirectReferenceToken ir && chainCount < 100)
|
||||
{
|
||||
throw new ApplicationException("Expected dictionary token, got " + item.GetType());
|
||||
if (sourceScanner == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
itemChain = sourceScanner.Get(ir.Data);
|
||||
|
||||
chainCount++;
|
||||
|
||||
if (itemChain is ObjectToken ot)
|
||||
{
|
||||
itemChain = ot.Data;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemChain is not DictionaryToken dt)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"While trying to copy token called {key} which should have been a dictionary token we found a token of type {item.GetType()}");
|
||||
}
|
||||
|
||||
if (dt.Data is Dictionary<string, IToken> mutable)
|
||||
@@ -37,30 +60,6 @@
|
||||
return created;
|
||||
}
|
||||
|
||||
public static Dictionary<string, IToken> GetOrCreateDict(this Dictionary<string, IToken> dict, string key)
|
||||
{
|
||||
if (dict.TryGetValue(key, out var item))
|
||||
{
|
||||
if (!(item is DictionaryToken dt))
|
||||
{
|
||||
throw new ApplicationException("Expected dictionary token, got " + item.GetType());
|
||||
}
|
||||
|
||||
if (dt.Data is Dictionary<string, IToken> mutable)
|
||||
{
|
||||
return mutable;
|
||||
}
|
||||
|
||||
mutable = dt.Data.
|
||||
ToDictionary(x => x.Key, x => x.Value);
|
||||
dict[key] = DictionaryToken.With(mutable);
|
||||
return mutable;
|
||||
}
|
||||
|
||||
var created = new Dictionary<string, IToken>();
|
||||
dict[key] = DictionaryToken.With(created);
|
||||
return created;
|
||||
}
|
||||
/// <summary>
|
||||
/// The purpose of this method is to resolve indirect reference. That mean copy the reference's content to the new document's stream
|
||||
/// and replace the indirect reference with the correct/new one
|
||||
|
||||
Reference in New Issue
Block a user