Skip to content

Commit 13eb59a

Browse files
Improved copying of tagged pages
Improved separation process of the existing tag structure into two parts in order to insert copied page tags between them: now this process doesn't rebuilt the whole tag tree
1 parent c1b45d1 commit 13eb59a

File tree

12 files changed

+282
-98
lines changed

12 files changed

+282
-98
lines changed

kernel/src/main/java/com/itextpdf/kernel/PdfException.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class PdfException extends RuntimeException {
2323
public static final String CannotCloseDocumentWithAlreadyFlushedPdfCatalog = "cannot.close.document.with.already.flushed.pdf.catalog";
2424
public static final String CannotConvertPdfArrayToRectanle = "cannot.convert.pdfarray.to.rectangle";
2525
public static final String CannotCopyFlushedObject = "cannot.copy.flushed.object";
26+
public static final String CannotCopyFlushedTag = "cannot.copy.flushed.tag";
2627
public static final String CannotCopyObjectContent = "cannot.copy.object.content";
2728
public static final String CannotCopyIndirectObjectFromTheDocumentThatIsBeingWritten = "cannot.copy.indirect.object.from.the.document.that.is.being.written";
2829
public static final String CannotCopyToDocumentOpenedInReadingMode = "cannot.copy.to.document.opened.in.reading.mode";
@@ -158,6 +159,7 @@ public class PdfException extends RuntimeException {
158159
public static final String StdcfNotFoundEncryption = "stdcf.not.found.encryption";
159160
public static final String StructureElementShallContainParentObject = "structure.element.shall.contain.parent.object";
160161
public static final String TagCannotBeMovedToTheAnotherDocumentsTagStructure = "tag.cannot.be.moved.to.the.another.documents.tag.structure";
162+
public static final String TagFromTheExistingTagStructureIsFlushedCannotAddCopiedPageTags = "tag.from.the.existing.tag.structure.is.flushed.cannot.add.copied.page.tags";
161163
public static final String TagTreePointerIsInInvalidStateItPointsAtFlushedElementUseMoveToRoot = "tagtreepointer.is.in.invalid.state.it.points.at.flushed.element.use.movetoroot";
162164
public static final String TagTreePointerIsInInvalidStateItPointsAtRemovedElementUseMoveToRoot = "tagtreepointer.is.in.invalid.state.it.points.at.removed.element.use.movetoroot";
163165
public static final String TextCannotBeNull = "text.cannot.be.null";

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfDocument.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -906,17 +906,19 @@ public List<PdfPage> copyPagesTo(Set<Integer> pagesToCopy, PdfDocument toDocumen
906906
Map<PdfPage, PdfPage> page2page = new LinkedHashMap<>();
907907
Map<PdfPage, List<PdfOutline>> page2Outlines = new HashMap<>();
908908
Set<PdfOutline> outlinesToCopy = new HashSet<>();
909+
int insertBefore = insertBeforePage;
910+
int numberOfPagesBeforeCopying = toDocument.getNumberOfPages();
909911
for (Integer pageNum : pagesToCopy) {
910912
PdfPage page = getPage(pageNum);
911913
PdfPage newPage = page.copyTo(toDocument, copier);
912914
copiedPages.add(newPage);
913915
page2page.put(page, newPage);
914-
if (insertBeforePage < toDocument.getNumberOfPages() + 1) {
915-
toDocument.addPage(insertBeforePage, newPage);
916+
if (insertBefore < toDocument.getNumberOfPages() + 1) {
917+
toDocument.addPage(insertBefore, newPage);
916918
} else {
917919
toDocument.addPage(newPage);
918920
}
919-
insertBeforePage++;
921+
insertBefore++;
920922
if (catalog.isOutlineMode()) {
921923
List<PdfOutline> pageOutlines = page.getOutlines(false);
922924
if (pageOutlines != null)
@@ -933,7 +935,7 @@ public List<PdfPage> copyPagesTo(Set<Integer> pagesToCopy, PdfDocument toDocumen
933935
if (tagStructureContext != null) {
934936
tagStructureContext.removeAllConnectionsToTags();
935937
}
936-
if (insertBeforePage > toDocument.getNumberOfPages()) {
938+
if (insertBeforePage > numberOfPagesBeforeCopying) {
937939
getStructTreeRoot().copyTo(toDocument, page2page);
938940
} else {
939941
getStructTreeRoot().copyTo(toDocument, insertBeforePage, page2page);

kernel/src/main/java/com/itextpdf/kernel/pdf/tagging/PdfStructElem.java

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ public PdfStructElem addKid(int index, PdfStructElem kid) {
207207
if (type == InlineLevel || type == Illustration) {
208208
throw new PdfException(PdfException.InlineLevelOrIllustrationElementCannotContainKids, getPdfObject());
209209
}
210-
addKidObject(index, kid.getPdfObject());
210+
addKidObject(getPdfObject(), index, kid.getPdfObject());
211211
return kid;
212212
}
213213

@@ -217,7 +217,7 @@ public PdfMcr addKid(PdfMcr kid) {
217217

218218
public PdfMcr addKid(int index, PdfMcr kid) {
219219
getDocument().getStructTreeRoot().getMcrManager().registerMcr(kid);
220-
addKidObject(index, kid.getPdfObject());
220+
addKidObject(getPdfObject(), index, kid.getPdfObject());
221221
return kid;
222222
}
223223

@@ -307,51 +307,50 @@ public void flush() {
307307
super.flush();
308308
}
309309

310-
@Override
311-
protected boolean isWrappedObjectMustBeIndirect() {
312-
return true;
313-
}
314-
315-
protected PdfDocument getDocument() {
316-
return getPdfObject().getIndirectReference().getDocument();
317-
}
318-
319-
private void addKidObjectToStructElemList(PdfObject k, List<IPdfStructElem> list) {
320-
if (k.isFlushed()) {
321-
list.add(null);
322-
return;
323-
}
324-
325-
list.add(convertPdfObjectToIPdfStructElem(k));
326-
}
327-
328-
private void addKidObject(int index, PdfObject kid) {
329-
PdfDictionary pdfObject = getPdfObject();
330-
if (pdfObject.isFlushed()) {
310+
static void addKidObject(PdfDictionary parent, int index, PdfObject kid) {
311+
if (parent.isFlushed()) {
331312
throw new PdfException(PdfException.CannotAddKidToTheFlushedElement);
332313
}
333-
if (!pdfObject.containsKey(PdfName.P)) {
334-
throw new PdfException(PdfException.StructureElementShallContainParentObject, pdfObject);
314+
if (!parent.containsKey(PdfName.P)) {
315+
throw new PdfException(PdfException.StructureElementShallContainParentObject, parent);
335316
}
336-
PdfObject k = getK();
317+
PdfObject k = parent.get(PdfName.K);
337318
if (k == null)
338-
pdfObject.put(PdfName.K, kid);
319+
parent.put(PdfName.K, kid);
339320
else {
340321
PdfArray a;
341322
if (k instanceof PdfArray) {
342323
a = (PdfArray) k;
343324
} else {
344325
a = new PdfArray();
345326
a.add(k);
346-
pdfObject.put(PdfName.K, a);
327+
parent.put(PdfName.K, a);
347328
}
348329
if (index == -1)
349330
a.add(kid);
350331
else
351332
a.add(index, kid);
352333
}
353334
if (kid instanceof PdfDictionary && isStructElem((PdfDictionary) kid))
354-
((PdfDictionary) kid).put(PdfName.P, pdfObject);
335+
((PdfDictionary) kid).put(PdfName.P, parent);
336+
}
337+
338+
@Override
339+
protected boolean isWrappedObjectMustBeIndirect() {
340+
return true;
341+
}
342+
343+
protected PdfDocument getDocument() {
344+
return getPdfObject().getIndirectReference().getDocument();
345+
}
346+
347+
private void addKidObjectToStructElemList(PdfObject k, List<IPdfStructElem> list) {
348+
if (k.isFlushed()) {
349+
list.add(null);
350+
return;
351+
}
352+
353+
list.add(convertPdfObjectToIPdfStructElem(k));
355354
}
356355

357356
private IPdfStructElem convertPdfObjectToIPdfStructElem(PdfObject obj) {

kernel/src/main/java/com/itextpdf/kernel/pdf/tagging/PdfStructTreeRoot.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,15 @@ void addKidObject(PdfDictionary structElem) {
258258
addKidObject(-1, structElem);
259259
}
260260

261+
void addKidObject(int index, PdfDictionary structElem) {
262+
if (index == -1)
263+
getKidsObject().add(structElem);
264+
else
265+
getKidsObject().add(index, structElem);
266+
if (PdfStructElem.isStructElem(structElem))
267+
structElem.put(PdfName.P, getPdfObject());
268+
}
269+
261270
@Override
262271
protected boolean isWrappedObjectMustBeIndirect() {
263272
return true;
@@ -273,15 +282,6 @@ private void flushAllKids(IPdfStructElem elem) {
273282
}
274283
}
275284

276-
private void addKidObject(int index, PdfDictionary structElem) {
277-
if (index == -1)
278-
getKidsObject().add(structElem);
279-
else
280-
getKidsObject().add(index, structElem);
281-
if (PdfStructElem.isStructElem(structElem))
282-
structElem.put(PdfName.P, getPdfObject());
283-
}
284-
285285
private void ifKidIsStructElementAddToList(PdfObject kid, List<IPdfStructElem> kids) {
286286
if (kid.isFlushed()) {
287287
kids.add(null);

0 commit comments

Comments
 (0)