Skip to content

Commit c10d8f3

Browse files
Implement PageFlushingHelper for deep page structure flushing/releasing
Misc: - Fix bug with reading out all encountered indirect objects during the process of object flushing. - Extend capabilities of PdfPage#flush flushing to annotations and thumb image; - Mark objects made indirect with FORBID_RELEASE; avoid objects reading on parent objects flushing; - Fix PdfAction#setAA modified state handling; - Avoid possibility of preserving released objects instances when working with pages, by storing page indirect reference instead of the direct object. In some cases it's required to explicitly use object indirect reference when adding the object to other objects, if the object is read from the document and might be released. We shall avoid situations when released object is stored somewhere inside the PDF structure. Such object instace cannot be flushed, it shall be reread instead. DEVSIX-2835
1 parent f9870c5 commit c10d8f3

File tree

21 files changed

+1338
-88
lines changed

21 files changed

+1338
-88
lines changed

forms/src/main/java/com/itextpdf/forms/PdfAcroForm.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ private Map<String, PdfFormField> iterateFields(PdfArray array, Map<String, PdfF
861861
int index = 1;
862862
for (PdfObject field : array) {
863863
if (field.isFlushed()) {
864-
logger.warn(LogMessageConstant.FORM_FIELD_WAS_FLUSHED);
864+
logger.info(LogMessageConstant.FORM_FIELD_WAS_FLUSHED);
865865
continue;
866866
}
867867
PdfFormField formField = PdfFormField.makeFormField(field, document);

forms/src/main/java/com/itextpdf/forms/fields/PdfFormField.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3557,8 +3557,7 @@ private PdfFont resolveFontName(String fontName) {
35573557
if (fontName != null && defaultFontDic != null) {
35583558
PdfDictionary daFontDict = defaultFontDic.getAsDictionary(new PdfName(fontName));
35593559
if (daFontDict != null) {
3560-
PdfFont daFont = getDocument().getFont(daFontDict);
3561-
return daFont != null ? daFont : PdfFontFactory.createFont(daFontDict);
3560+
return getDocument().getFont(daFontDict);
35623561
}
35633562
}
35643563
return null;

forms/src/test/java/com/itextpdf/forms/PdfFormCopyTest.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,6 @@ public void copyFieldsTest09() throws IOException, InterruptedException {
399399
}
400400

401401
@Test
402-
@LogMessages(messages = {
403-
@LogMessage(messageTemplate = LogMessageConstant.FORM_FIELD_WAS_FLUSHED, count = 84)
404-
})
405402
public void copyFieldsTest10() throws IOException, InterruptedException {
406403
String srcFilename = sourceFolder + "datasheet.pdf";
407404
String destFilename = destinationFolder + "copyFields10.pdf";
@@ -419,9 +416,6 @@ public void copyFieldsTest10() throws IOException, InterruptedException {
419416
}
420417

421418
@Test
422-
@LogMessages(messages = {
423-
@LogMessage(messageTemplate = LogMessageConstant.FORM_FIELD_WAS_FLUSHED, count = 28)
424-
})
425419
public void copyFieldsTest11() throws IOException, InterruptedException {
426420
String srcFilename1 = sourceFolder + "datasheet.pdf";
427421
String srcFilename2 = sourceFolder + "datasheet2.pdf";
@@ -444,9 +438,6 @@ public void copyFieldsTest11() throws IOException, InterruptedException {
444438
}
445439

446440
@Test
447-
@LogMessages(messages = {
448-
@LogMessage(messageTemplate = LogMessageConstant.FORM_FIELD_WAS_FLUSHED, count = 28)
449-
})
450441
public void copyFieldsTest12() throws IOException, InterruptedException {
451442
String srcFilename1 = sourceFolder + "datasheet.pdf";
452443
String srcFilename2 = sourceFolder + "datasheet2.pdf";

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ public class PdfException extends RuntimeException {
164164
public static final String FilterCcittfaxdecodeIsOnlySupportedForImages = "Filter CCITTFaxDecode is only supported for images";
165165
public static final String FilterIsNotANameOrArray = "filter is not a name or array.";
166166
public static final String FlushedPageCannotBeAddedOrInserted = "Flushed page cannot be added or inserted.";
167+
public static final String FlushingHelperFLushingModeIsNotForDocReadingMode = "Flushing writes the object to the output stream and releases it from memory. It is only possible for documents that have a PdfWriter associated with them. Use PageFlushingHelper#releaseDeep method instead.";
167168
public static final String FontAndSizeMustBeSetBeforeWritingAnyText = "Font and size must be set before writing any text.";
168169
public static final String FontEmbeddingIssue = "Font embedding issue.";
169170
public static final String FontProviderNotSetFontFamilyNotResolved = "FontProvider and FontSet are empty. Cannot resolve font family name (see ElementPropertyContainer#setFontFamily) without initialized FontProvider (see RootElement#setFontProvider).";

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

Lines changed: 580 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ public class PdfDocument implements IEventDispatcher, Closeable, Serializable {
112112

113113
/**
114114
* Currently active page.
115+
* @deprecated Will be removed in iText 7.2
115116
*/
117+
@Deprecated
116118
protected PdfPage currentPage = null;
117119

118120
/**
@@ -473,7 +475,7 @@ public PdfPage addNewPage(int index, PageSize pageSize) {
473475
currentPage = page;
474476
dispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.START_PAGE, page));
475477
dispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.INSERT_PAGE, page));
476-
return currentPage;
478+
return page;
477479
}
478480

479481
/**
@@ -503,7 +505,7 @@ public PdfPage addPage(int index, PdfPage page) {
503505
checkAndAddPage(index, page);
504506
currentPage = page;
505507
dispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.INSERT_PAGE, page));
506-
return currentPage;
508+
return page;
507509
}
508510

509511
/**
@@ -829,6 +831,7 @@ public void close() {
829831
catalog.getPdfObject().flush(false);
830832
}
831833

834+
832835
if (info.getPdfObject().isModified()) {
833836
info.getPdfObject().flush(false);
834837
}
@@ -1708,6 +1711,7 @@ public PdfFont getDefaultFont() {
17081711
*/
17091712
public PdfFont addFont(PdfFont font) {
17101713
font.makeIndirect(this);
1714+
font.setForbidRelease(); // forbid release for font dictionaries that are stored in #documentFonts collection
17111715
documentFonts.put(font.getPdfObject().getIndirectReference(), font);
17121716
return font;
17131717
}
@@ -1748,6 +1752,10 @@ PdfXrefTable getXref() {
17481752
return xref;
17491753
}
17501754

1755+
boolean isDocumentFont(PdfIndirectReference indRef) {
1756+
return indRef != null && documentFonts.containsKey(indRef);
1757+
}
1758+
17511759
/**
17521760
* Initialize {@link TagStructureContext}.
17531761
*/

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ public class PdfName extends PdfPrimitiveObject implements Comparable<PdfName> {
282282
public static final PdfName Double = createDirectName("Double");
283283
public static final PdfName DP = createDirectName("DP");
284284
public static final PdfName Dp = createDirectName("Dp");
285+
public static final PdfName DPart = createDirectName("DPart");
285286
public static final PdfName DR = createDirectName("DR");
286287
public static final PdfName Draft = createDirectName("Draft");
287288
public static final PdfName DS = createDirectName("DS");
@@ -534,6 +535,7 @@ public class PdfName extends PdfPrimitiveObject implements Comparable<PdfName> {
534535
public static final PdfName MuLaw = createDirectName("muLaw");
535536
public static final PdfName Multiply = createDirectName("Multiply");
536537
public static final PdfName N = createDirectName("N");
538+
public static final PdfName NA = createDirectName("NA");
537539
public static final PdfName Name = createDirectName("Name");
538540
public static final PdfName Named = createDirectName("Named");
539541
public static final PdfName Names = createDirectName("Names");
@@ -718,10 +720,11 @@ public class PdfName extends PdfPrimitiveObject implements Comparable<PdfName> {
718720
public static final PdfName Schema = createDirectName("Schema");
719721
public static final PdfName Scope = createDirectName("Scope");
720722
public static final PdfName Screen = createDirectName("Screen");
723+
public static final PdfName SD = createDirectName("SD");
721724
public static final PdfName Sect = createDirectName("Sect");
722725
public static final PdfName Separation = createDirectName("Separation");
723726
public static final PdfName SeparationColorNames = createDirectName("SeparationColorNames");
724-
public static final PdfName SD = createDirectName("SD");
727+
public static final PdfName SeparationInfo = createDirectName("SeparationInfo");
725728
public static final PdfName Shading = createDirectName("Shading");
726729
public static final PdfName ShadingType = createDirectName("ShadingType");
727730
public static final PdfName SetOCGState = createDirectName("SetOCGState");
@@ -782,14 +785,12 @@ public class PdfName extends PdfPrimitiveObject implements Comparable<PdfName> {
782785
public static final PdfName Subtype2 = createDirectName("Subtype2");
783786
public static final PdfName Supplement = createDirectName("Supplement");
784787
public static final PdfName Sy = createDirectName("Sy");
785-
public static final PdfName Symbol = new PdfName("Symbol");
788+
public static final PdfName Symbol = createDirectName("Symbol");
786789
public static final PdfName Synchronous = createDirectName("Synchronous");
787790
public static final PdfName T = createDirectName("T");
788791
public static final PdfName Tag = createDirectName("Tag");
789792
public static final PdfName TBorderStyle = createDirectName("TBorderStyle");
790-
public static final PdfName Trans = createDirectName("Trans");
791-
public static final PdfName Trapped = createDirectName("Trapped");
792-
public static final PdfName True = createDirectName("true");
793+
public static final PdfName TA = createDirectName("TA");
793794
public static final PdfName Table = createDirectName("Table");
794795
public static final PdfName Tabs = createDirectName("Tabs");
795796
public static final PdfName TBody = createDirectName("TBody");
@@ -822,12 +823,15 @@ public class PdfName extends PdfPrimitiveObject implements Comparable<PdfName> {
822823
public static final PdfName ToUnicode = createDirectName("ToUnicode");
823824
public static final PdfName TR = createDirectName("TR");
824825
public static final PdfName TR2 = createDirectName("TR2");
826+
public static final PdfName Trans = createDirectName("Trans");
825827
public static final PdfName TransformMethod = createDirectName("TransformMethod");
826828
public static final PdfName TransformParams = createDirectName("TransformParams");
827829
public static final PdfName Transparency = createDirectName("Transparency");
828830
public static final PdfName TrapNet = createDirectName("TrapNet");
831+
public static final PdfName Trapped = createDirectName("Trapped");
829832
public static final PdfName TrapRegions = createDirectName("TrapRegions");
830833
public static final PdfName TrapStyles = createDirectName("TrapStyles");
834+
public static final PdfName True = createDirectName("true");
831835
public static final PdfName TrueType = createDirectName("TrueType");
832836
public static final PdfName TU = createDirectName("TU");
833837
public static final PdfName TwoColumnLeft = createDirectName("TwoColumnLeft");
@@ -904,7 +908,7 @@ public class PdfName extends PdfPrimitiveObject implements Comparable<PdfName> {
904908
public static final PdfName XStep = createDirectName("XStep");
905909
public static final PdfName XYZ = createDirectName("XYZ");
906910
public static final PdfName YStep = createDirectName("YStep");
907-
public static final PdfName ZapfDingbats = new PdfName("ZapfDingbats");
911+
public static final PdfName ZapfDingbats = createDirectName("ZapfDingbats");
908912
public static final PdfName zh_Latn_pinyin = createDirectName("zh-Latn-pinyin");
909913
public static final PdfName zh_Latn_wadegile = createDirectName("zh-Latn-wadegile");
910914
public static final PdfName Zoom = createDirectName("Zoom");

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,11 @@ public PdfObject makeIndirect(PdfDocument document, PdfIndirectReference referen
232232
indirectReference = document.createNextIndirectReference();
233233
indirectReference.setRefersTo(this);
234234
} else {
235+
reference.setState(MODIFIED);
235236
indirectReference = reference;
236237
indirectReference.setRefersTo(this);
237238
}
239+
setState(FORBID_RELEASE);
238240
clearState(MUST_BE_INDIRECT);
239241
return this;
240242
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,9 @@ private void write(PdfIndirectReference indirectReference) {
219219
Logger logger = LoggerFactory.getLogger(PdfOutputStream.class);
220220
logger.error(LogMessageConstant.FLUSHED_OBJECT_CONTAINS_FREE_REFERENCE);
221221
write(PdfNull.PDF_NULL);
222-
} else if (indirectReference.getRefersTo() == null) {
222+
} else if (indirectReference.refersTo == null
223+
&& (indirectReference.checkState(PdfObject.MODIFIED) || indirectReference.getReader() == null
224+
|| !(indirectReference.getOffset() > 0 || indirectReference.getIndex() >= 0))) {
223225
Logger logger = LoggerFactory.getLogger(PdfOutputStream.class);
224226
logger.error(LogMessageConstant.FLUSHED_OBJECT_CONTAINS_REFERENCE_WHICH_NOT_REFER_TO_ANY_OBJECT);
225227
write(PdfNull.PDF_NULL);

0 commit comments

Comments
 (0)