Skip to content

Commit 7c612e2

Browse files
LodrKumquatiText-CI
authored andcommitted
Fix several issues with PdfOutline processing
- support processing of incorrect hierarchy of outlines when merging - process PdfNumber as page argument for outline destinations - support copying of named destinations DEVSIX-2517 Autoported commit. Original commit hash: [0e5b707dd]
1 parent 5667e27 commit 7c612e2

File tree

11 files changed

+71
-11
lines changed

11 files changed

+71
-11
lines changed

itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfDestinationTest.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,38 @@ public virtual void DestCopyingTest05() {
168168
));
169169
}
170170

171+
/// <exception cref="System.IO.IOException"/>
172+
/// <exception cref="System.Exception"/>
173+
[NUnit.Framework.Test]
174+
public virtual void DestCopyingTest06() {
175+
String srcFile = sourceFolder + "sourceWithNamedDestination.pdf";
176+
String outFile = destinationFolder + "destCopyingTest06.pdf";
177+
String cmpFile = sourceFolder + "cmp_destCopyingTest06.pdf";
178+
PdfDocument srcDoc = new PdfDocument(new PdfReader(srcFile));
179+
PdfDocument destDoc = new PdfDocument(new PdfWriter(outFile));
180+
srcDoc.CopyPagesTo(JavaUtil.ArraysAsList(1, 2, 1), destDoc);
181+
destDoc.Close();
182+
srcDoc.Close();
183+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFile, cmpFile, destinationFolder, "diff_"
184+
));
185+
}
186+
187+
/// <exception cref="System.IO.IOException"/>
188+
/// <exception cref="System.Exception"/>
189+
[NUnit.Framework.Test]
190+
public virtual void DestCopyingTest07() {
191+
String srcFile = sourceFolder + "sourceStringDestWithPageNumber.pdf";
192+
String outFile = destinationFolder + "destCopyingTest07.pdf";
193+
String cmpFile = sourceFolder + "cmp_destCopyingTest07.pdf";
194+
PdfDocument srcDoc = new PdfDocument(new PdfReader(srcFile));
195+
PdfDocument destDoc = new PdfDocument(new PdfWriter(outFile));
196+
srcDoc.CopyPagesTo(JavaUtil.ArraysAsList(1, 2, 1), destDoc);
197+
destDoc.Close();
198+
srcDoc.Close();
199+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFile, cmpFile, destinationFolder, "diff_"
200+
));
201+
}
202+
171203
/// <exception cref="System.IO.IOException"/>
172204
/// <exception cref="System.Exception"/>
173205
[NUnit.Framework.Test]

itext.tests/itext.kernel.tests/itext/kernel/utils/PdfMergerTest.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,5 +242,30 @@ public virtual void MergeTableWithEmptyTdTest() {
242242
NUnit.Framework.Assert.Fail(errorMessage);
243243
}
244244
}
245+
246+
/// <exception cref="System.IO.IOException"/>
247+
/// <exception cref="System.Exception"/>
248+
[NUnit.Framework.Test]
249+
[LogMessage(iText.IO.LogMessageConstant.NAME_ALREADY_EXISTS_IN_THE_NAME_TREE, Count = 2)]
250+
public virtual void MergeOutlinesNamedDestinations() {
251+
String filename = sourceFolder + "outlinesNamedDestinations.pdf";
252+
String resultFile = destinationFolder + "mergeOutlinesNamedDestinations.pdf";
253+
PdfReader reader = new PdfReader(filename);
254+
PdfDocument sourceDoc = new PdfDocument(reader);
255+
PdfDocument output = new PdfDocument(new PdfWriter(resultFile));
256+
PdfMerger merger = new PdfMerger(output).SetCloseSourceDocuments(false);
257+
merger.Merge(sourceDoc, 2, 3);
258+
merger.Merge(sourceDoc, 2, 3);
259+
sourceDoc.Close();
260+
reader.Close();
261+
merger.Close();
262+
output.Close();
263+
CompareTool compareTool = new CompareTool();
264+
String errorMessage = compareTool.CompareByContent(resultFile, sourceFolder + "cmp_mergeOutlinesNamedDestinations.pdf"
265+
, destinationFolder, "diff_");
266+
if (errorMessage != null) {
267+
NUnit.Framework.Assert.Fail(errorMessage);
268+
}
269+
}
245270
}
246271
}

itext/itext.kernel/itext/kernel/pdf/PdfCatalog.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -464,19 +464,26 @@ internal virtual PdfDestination CopyDestination(PdfObject dest, IDictionary<PdfP
464464
}
465465
}
466466
else {
467-
if (dest.IsString()) {
467+
if (dest.IsString() || dest.IsName()) {
468468
PdfNameTree destsTree = GetNameTree(PdfName.Dests);
469469
IDictionary<String, PdfObject> dests = destsTree.GetNames();
470-
String srcDestName = ((PdfString)dest).ToUnicodeString();
470+
String srcDestName = dest.IsString() ? ((PdfString)dest).ToUnicodeString() : ((PdfName)dest).GetValue();
471471
PdfArray srcDestArray = (PdfArray)dests.Get(srcDestName);
472472
if (srcDestArray != null) {
473473
PdfObject pageObject = srcDestArray.Get(0);
474+
if (pageObject is PdfNumber) {
475+
pageObject = GetDocument().GetPage(((PdfNumber)pageObject).IntValue() + 1).GetPdfObject();
476+
}
474477
foreach (PdfPage oldPage in page2page.Keys) {
475478
if (oldPage.GetPdfObject() == pageObject) {
476479
d = new PdfStringDestination(srcDestName);
477480
if (!IsEqualSameNameDestExist(page2page, toDocument, srcDestName, srcDestArray, oldPage)) {
478481
// in the copiedArray old page ref will be correctly replaced by the new page ref as this page is already copied
479482
PdfArray copiedArray = (PdfArray)srcDestArray.CopyTo(toDocument, false);
483+
// here we can safely replace first item of the array because array of NamedDestination or StringDestination
484+
// never refers to page in another document via PdfNumber, but should always refer to page within current document
485+
// via page object reference.
486+
copiedArray.Set(0, page2page.Get(oldPage).GetPdfObject());
480487
toDocument.AddNamedDestination(srcDestName, copiedArray);
481488
}
482489
break;
@@ -508,6 +515,9 @@ private bool IsEqualSameNameDestExist(IDictionary<PdfPage, PdfPage> page2page, P
508515

509516
private void AddOutlineToPage(PdfOutline outline, IDictionary<String, PdfObject> names) {
510517
PdfObject pageObj = outline.GetDestination().GetDestinationPage(names);
518+
if (pageObj is PdfNumber) {
519+
pageObj = GetDocument().GetPage(((PdfNumber)pageObj).IntValue() + 1).GetPdfObject();
520+
}
511521
if (pageObj != null) {
512522
IList<PdfOutline> outs = pagesWithOutlines.Get(pageObj);
513523
if (outs == null) {
@@ -637,11 +647,6 @@ private void ConstructOutlines(PdfDictionary outlineRoot, IDictionary<String, Pd
637647
if (first != null) {
638648
parentOutlineMap.Put(current, currentOutline);
639649
}
640-
else {
641-
if (current == parent.GetAsDictionary(PdfName.Last)) {
642-
parentOutlineMap.JRemove(parent);
643-
}
644-
}
645650
current = GetNextOutline(first, next, parent);
646651
}
647652
}

itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,9 +1105,7 @@ public virtual IList<PdfPage> CopyPagesTo(IList<int> pagesToCopy, iText.Kernel.P
11051105
PdfPage page = GetPage((int)pageNum);
11061106
PdfPage newPage = page.CopyTo(toDocument, copier);
11071107
copiedPages.Add(newPage);
1108-
if (!page2page.ContainsKey(page)) {
1109-
page2page.Put(page, newPage);
1110-
}
1108+
page2page.Put(page, newPage);
11111109
if (lastCopiedPageNum >= pageNum) {
11121110
rangesOfPagesWithIncreasingNumbers.Add(new Dictionary<PdfPage, PdfPage>());
11131111
}

0 commit comments

Comments
 (0)