diff --git a/itext.tests/itext.barcodes.tests/itext.barcodes.tests.csproj b/itext.tests/itext.barcodes.tests/itext.barcodes.tests.csproj index 1e6cfa2a6e..01ceb83efb 100644 --- a/itext.tests/itext.barcodes.tests/itext.barcodes.tests.csproj +++ b/itext.tests/itext.barcodes.tests/itext.barcodes.tests.csproj @@ -33,7 +33,6 @@ - diff --git a/itext.tests/itext.commons.tests/itext.commons.tests.csproj b/itext.tests/itext.commons.tests/itext.commons.tests.csproj index 26bc070a71..50ac589f5b 100644 --- a/itext.tests/itext.commons.tests/itext.commons.tests.csproj +++ b/itext.tests/itext.commons.tests/itext.commons.tests.csproj @@ -33,7 +33,6 @@ - diff --git a/itext.tests/itext.forms.tests/itext.forms.tests.csproj b/itext.tests/itext.forms.tests/itext.forms.tests.csproj index 6fa93ea76d..051da61660 100644 --- a/itext.tests/itext.forms.tests/itext.forms.tests.csproj +++ b/itext.tests/itext.forms.tests/itext.forms.tests.csproj @@ -35,7 +35,6 @@ - diff --git a/itext.tests/itext.io.tests/itext.io.tests.csproj b/itext.tests/itext.io.tests/itext.io.tests.csproj index bb3b65616b..3b4d7ddfb8 100644 --- a/itext.tests/itext.io.tests/itext.io.tests.csproj +++ b/itext.tests/itext.io.tests/itext.io.tests.csproj @@ -28,7 +28,6 @@ - 1701;1702;1591;1570;1572;1573;1574;1580;1584;1658 diff --git a/itext.tests/itext.kernel.tests/itext.kernel.tests.csproj b/itext.tests/itext.kernel.tests/itext.kernel.tests.csproj index 9c3449b77b..a3b02580a8 100644 --- a/itext.tests/itext.kernel.tests/itext.kernel.tests.csproj +++ b/itext.tests/itext.kernel.tests/itext.kernel.tests.csproj @@ -33,7 +33,6 @@ - diff --git a/itext.tests/itext.kernel.tests/itext/kernel/pdf/OcgPropertiesCopierTest.cs b/itext.tests/itext.kernel.tests/itext/kernel/pdf/OcgPropertiesCopierTest.cs index 470c389341..ee54bb00ba 100644 --- a/itext.tests/itext.kernel.tests/itext/kernel/pdf/OcgPropertiesCopierTest.cs +++ b/itext.tests/itext.kernel.tests/itext/kernel/pdf/OcgPropertiesCopierTest.cs @@ -544,8 +544,8 @@ public virtual void CopyDFieldsToEmptyDocumentTest() { NUnit.Framework.Assert.AreEqual("Off1", off.GetAsDictionary(0).GetAsString(PdfName.Name).ToUnicodeString() ); NUnit.Framework.Assert.IsNull(dDict.GetAsArray(PdfName.Creator)); - NUnit.Framework.Assert.AreEqual("OCConfigName0", dDict.GetAsString(PdfName.Name).ToUnicodeString()); - NUnit.Framework.Assert.IsNull(dDict.GetAsName(PdfName.BaseState)); + NUnit.Framework.Assert.AreEqual("Name", dDict.GetAsString(PdfName.Name).ToUnicodeString()); + NUnit.Framework.Assert.AreEqual(PdfName.ON, dDict.GetAsName(PdfName.BaseState)); PdfArray asArray = dDict.GetAsArray(PdfName.AS); NUnit.Framework.Assert.AreEqual(1, asArray.Size()); NUnit.Framework.Assert.AreEqual(1, asArray.GetAsDictionary(0).GetAsArray(PdfName.Category).Size()); @@ -553,8 +553,8 @@ public virtual void CopyDFieldsToEmptyDocumentTest() { (0)); NUnit.Framework.Assert.AreEqual("noPrint1", asArray.GetAsDictionary(0).GetAsArray(PdfName.OCGs).GetAsDictionary (0).GetAsString(PdfName.Name).ToUnicodeString()); - NUnit.Framework.Assert.IsNull(dDict.GetAsName(PdfName.Intent)); - NUnit.Framework.Assert.IsNull(dDict.GetAsName(PdfName.ListMode)); + NUnit.Framework.Assert.AreEqual(PdfName.View, dDict.GetAsName(PdfName.Intent)); + NUnit.Framework.Assert.AreEqual(PdfName.VisiblePages, dDict.GetAsName(PdfName.ListMode)); } [NUnit.Framework.Test] @@ -665,8 +665,8 @@ public virtual void CopyDFieldsToDocumentWithDDictTest() { NUnit.Framework.Assert.AreEqual("from_Off1", off.GetAsDictionary(2).GetAsString(PdfName.Name).ToUnicodeString ()); NUnit.Framework.Assert.IsNull(dDict.GetAsArray(PdfName.Creator)); - NUnit.Framework.Assert.AreEqual("OCConfigName0", dDict.GetAsString(PdfName.Name).ToUnicodeString()); - NUnit.Framework.Assert.IsNull(dDict.GetAsName(PdfName.BaseState)); + NUnit.Framework.Assert.AreEqual("Name", dDict.GetAsString(PdfName.Name).ToUnicodeString()); + NUnit.Framework.Assert.AreEqual(PdfName.ON, dDict.GetAsName(PdfName.BaseState)); PdfArray asArray = dDict.GetAsArray(PdfName.AS); NUnit.Framework.Assert.AreEqual(1, asArray.Size()); NUnit.Framework.Assert.AreEqual(1, asArray.GetAsDictionary(0).GetAsArray(PdfName.Category).Size()); @@ -677,8 +677,8 @@ public virtual void CopyDFieldsToDocumentWithDDictTest() { (0).GetAsString(PdfName.Name).ToUnicodeString()); NUnit.Framework.Assert.AreEqual("from_noPrint1", asArray.GetAsDictionary(0).GetAsArray(PdfName.OCGs).GetAsDictionary (1).GetAsString(PdfName.Name).ToUnicodeString()); - NUnit.Framework.Assert.IsNull(dDict.GetAsName(PdfName.Intent)); - NUnit.Framework.Assert.IsNull(dDict.GetAsName(PdfName.ListMode)); + NUnit.Framework.Assert.AreEqual(PdfName.View, dDict.GetAsName(PdfName.Intent)); + NUnit.Framework.Assert.AreEqual(PdfName.VisiblePages, dDict.GetAsName(PdfName.ListMode)); } // Copy OCGs from different locations (OCMDs, annotations, content streams, xObjects) test block @@ -976,12 +976,13 @@ private static byte[] GetDocumentWithAllDFields() { off2.SetOn(false); pdfResource.MakeIndirect(fromDocument); PdfOCProperties ocProperties = fromDocument.GetCatalog().GetOCProperties(true); + PdfDictionary dDictionary = ocProperties.GetPdfObject().GetAsDictionary(PdfName.D); // Creator (will be not copied) - ocProperties.GetPdfObject().Put(PdfName.Creator, new PdfString("CreatorName", PdfEncodings.UNICODE_BIG)); + dDictionary.Put(PdfName.Creator, new PdfString("CreatorName", PdfEncodings.UNICODE_BIG)); // Name (will be automatically changed) - ocProperties.GetPdfObject().Put(PdfName.Name, new PdfString("Name", PdfEncodings.UNICODE_BIG)); + dDictionary.Put(PdfName.Name, new PdfString("Name", PdfEncodings.UNICODE_BIG)); // BaseState (will be not copied) - ocProperties.GetPdfObject().Put(PdfName.BaseState, PdfName.OFF); + dDictionary.Put(PdfName.BaseState, PdfName.ON); // AS (will be automatically changed) PdfArray asArray = new PdfArray(); PdfDictionary dict = new PdfDictionary(); @@ -993,14 +994,14 @@ private static byte[] GetDocumentWithAllDFields() { ocgs.Add(locked1.GetPdfObject()); dict.Put(PdfName.OCGs, ocgs); asArray.Add(dict); - ocProperties.GetPdfObject().Put(PdfName.AS, asArray); + dDictionary.Put(PdfName.AS, asArray); PdfLayer noPrint1 = new PdfLayer("noPrint1", fromDocument); pdfResource.AddProperties(noPrint1.GetPdfObject()); noPrint1.SetPrint("Print", false); // Intent (will be not copied) - ocProperties.GetPdfObject().Put(PdfName.Intent, PdfName.Design); + dDictionary.Put(PdfName.Intent, PdfName.View); // ListMode (will be not copied) - ocProperties.GetPdfObject().Put(PdfName.ListMode, PdfName.VisiblePages); + dDictionary.Put(PdfName.ListMode, PdfName.VisiblePages); } fromDocBytes = outputStream.ToArray(); } diff --git a/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfCopyTest.cs b/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfCopyTest.cs index d3d01e9543..68d6d8b201 100644 --- a/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfCopyTest.cs +++ b/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfCopyTest.cs @@ -323,6 +323,19 @@ public virtual void CopyPagesLinkAnnotationTest() { )); } + [NUnit.Framework.Test] + public virtual void CopyDocWithFullDDictionary() { + String outFileName = destinationFolder + "copyDocWithDDictionary.pdf"; + String cmpFileName = sourceFolder + "cmp_copyDocWithDDictionary.pdf"; + PdfDocument inPdf = new PdfDocument(new PdfReader(sourceFolder + "DocWithDDictionary.pdf")); + PdfDocument outPdf = new PdfDocument(new PdfWriter(outFileName)); + inPdf.CopyPagesTo(1, 1, outPdf); + inPdf.Close(); + outPdf.Close(); + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder + )); + } + private IList GetPdfAnnotations(PdfDocument pdfDoc) { int number = pdfDoc.GetNumberOfPages(); List annotations = new List(); diff --git a/itext.tests/itext.kernel.tests/itext/kernel/pdf/layer/PdfLayerTest.cs b/itext.tests/itext.kernel.tests/itext/kernel/pdf/layer/PdfLayerTest.cs index cb32c8f062..b529d1b5dd 100644 --- a/itext.tests/itext.kernel.tests/itext/kernel/pdf/layer/PdfLayerTest.cs +++ b/itext.tests/itext.kernel.tests/itext/kernel/pdf/layer/PdfLayerTest.cs @@ -330,7 +330,7 @@ public virtual void TestInStamperMode1() { (destinationFolder + "output_copy_layered.pdf")); pdfDoc.Close(); NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(destinationFolder + "output_copy_layered.pdf" - , sourceFolder + "input_layered.pdf", destinationFolder, "diff")); + , sourceFolder + "cmp_output_copy_layered.pdf", destinationFolder, "diff")); } [NUnit.Framework.Test] diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfCopyTest/DocWithDDictionary.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfCopyTest/DocWithDDictionary.pdf new file mode 100644 index 0000000000..fca8cebb4a Binary files /dev/null and b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfCopyTest/DocWithDDictionary.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfCopyTest/cmp_copyDocWithDDictionary.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfCopyTest/cmp_copyDocWithDDictionary.pdf new file mode 100644 index 0000000000..87f7225636 Binary files /dev/null and b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfCopyTest/cmp_copyDocWithDDictionary.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfOutlineTest/cmp_outlineTypeNull.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfOutlineTest/cmp_outlineTypeNull.pdf index 6d607161b8..01ea9dc7e8 100644 Binary files a/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfOutlineTest/cmp_outlineTypeNull.pdf and b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/PdfOutlineTest/cmp_outlineTypeNull.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/layer/PdfLayerTest/cmp_output_copy_layered.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/layer/PdfLayerTest/cmp_output_copy_layered.pdf new file mode 100644 index 0000000000..d957af711a Binary files /dev/null and b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/layer/PdfLayerTest/cmp_output_copy_layered.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/layer/PdfLayerTest/ocpConfigs.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/layer/PdfLayerTest/ocpConfigs.pdf index 5d68f5028c..0f217c612e 100644 Binary files a/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/layer/PdfLayerTest/ocpConfigs.pdf and b/itext.tests/itext.kernel.tests/resources/itext/kernel/pdf/layer/PdfLayerTest/ocpConfigs.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_MergeWithSameNamedOCG.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_MergeWithSameNamedOCG.pdf index 652264cdc9..db714d7a22 100644 Binary files a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_MergeWithSameNamedOCG.pdf and b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_MergeWithSameNamedOCG.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithComplexOCGTest.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithComplexOCGTest.pdf index fc84730472..3ee417dfb2 100644 Binary files a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithComplexOCGTest.pdf and b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithComplexOCGTest.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithComplexOCGTwiceTest.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithComplexOCGTwiceTest.pdf index 949e9be430..54713f1af3 100644 Binary files a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithComplexOCGTwiceTest.pdf and b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithComplexOCGTwiceTest.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithOCGTest.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithOCGTest.pdf index 4820634f85..1d2e7eff6f 100644 Binary files a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithOCGTest.pdf and b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergePdfWithOCGTest.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergeTwoPagePdfWithComplexOCGTest.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergeTwoPagePdfWithComplexOCGTest.pdf index be203568cf..b5371972c0 100644 Binary files a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergeTwoPagePdfWithComplexOCGTest.pdf and b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergeTwoPagePdfWithComplexOCGTest.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergeWithSameNamedOCMD.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergeWithSameNamedOCMD.pdf index 2fee600a7c..d20100d15d 100644 Binary files a/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergeWithSameNamedOCMD.pdf and b/itext.tests/itext.kernel.tests/resources/itext/kernel/utils/PdfMergerTest/cmp_mergeWithSameNamedOCMD.pdf differ diff --git a/itext.tests/itext.layout.tests/itext.layout.tests.csproj b/itext.tests/itext.layout.tests/itext.layout.tests.csproj index 9f68a42563..6f794def70 100644 --- a/itext.tests/itext.layout.tests/itext.layout.tests.csproj +++ b/itext.tests/itext.layout.tests/itext.layout.tests.csproj @@ -33,7 +33,6 @@ - diff --git a/itext.tests/itext.pdfa.tests/itext.pdfa.tests.csproj b/itext.tests/itext.pdfa.tests/itext.pdfa.tests.csproj index 0cbeaf9d26..1f2b3356cf 100644 --- a/itext.tests/itext.pdfa.tests/itext.pdfa.tests.csproj +++ b/itext.tests/itext.pdfa.tests/itext.pdfa.tests.csproj @@ -33,7 +33,6 @@ - diff --git a/itext.tests/itext.pdftest.tests/itext.pdftest.tests.csproj b/itext.tests/itext.pdftest.tests/itext.pdftest.tests.csproj index 7161149c66..7f4bb7afa5 100644 --- a/itext.tests/itext.pdftest.tests/itext.pdftest.tests.csproj +++ b/itext.tests/itext.pdftest.tests/itext.pdftest.tests.csproj @@ -33,7 +33,6 @@ - diff --git a/itext.tests/itext.pdfua.tests/itext.pdfua.tests.csproj b/itext.tests/itext.pdfua.tests/itext.pdfua.tests.csproj index a623a27ccc..28456d3fda 100644 --- a/itext.tests/itext.pdfua.tests/itext.pdfua.tests.csproj +++ b/itext.tests/itext.pdfua.tests/itext.pdfua.tests.csproj @@ -33,7 +33,6 @@ - diff --git a/itext.tests/itext.sign.tests/itext.sign.tests.csproj b/itext.tests/itext.sign.tests/itext.sign.tests.csproj index 8f90f83b4f..fb883e150c 100644 --- a/itext.tests/itext.sign.tests/itext.sign.tests.csproj +++ b/itext.tests/itext.sign.tests/itext.sign.tests.csproj @@ -33,7 +33,6 @@ - diff --git a/itext.tests/itext.styledxmlparser.tests/itext.styledxmlparser.tests.csproj b/itext.tests/itext.styledxmlparser.tests/itext.styledxmlparser.tests.csproj index 04730baae5..f9ee967600 100644 --- a/itext.tests/itext.styledxmlparser.tests/itext.styledxmlparser.tests.csproj +++ b/itext.tests/itext.styledxmlparser.tests/itext.styledxmlparser.tests.csproj @@ -27,7 +27,6 @@ - diff --git a/itext.tests/itext.svg.tests/itext.svg.tests.csproj b/itext.tests/itext.svg.tests/itext.svg.tests.csproj index bebcf16385..5c83e67eba 100644 --- a/itext.tests/itext.svg.tests/itext.svg.tests.csproj +++ b/itext.tests/itext.svg.tests/itext.svg.tests.csproj @@ -27,7 +27,6 @@ - diff --git a/itext/itext.kernel/itext/kernel/logs/KernelLogMessageConstant.cs b/itext/itext.kernel/itext/kernel/logs/KernelLogMessageConstant.cs index 8d6a15adf2..6e47fa1586 100644 --- a/itext/itext.kernel/itext/kernel/logs/KernelLogMessageConstant.cs +++ b/itext/itext.kernel/itext/kernel/logs/KernelLogMessageConstant.cs @@ -84,6 +84,8 @@ public sealed class KernelLogMessageConstant { public const String FORMFIELD_ANNOTATION_WILL_NOT_BE_FLATTENED = "Form field annotation flattening is not " + "supported. Use the PdfAcroForm#flattenFields() method instead."; + public const String INVALID_DDICTIONARY_FIELD_VALUE = "The default configuration dictionary field {0}" + " has a value of {1}, which is not the required value for this field. The field will not be processed."; + private KernelLogMessageConstant() { } //Private constructor will prevent the instantiation of this class directly diff --git a/itext/itext.kernel/itext/kernel/pdf/OcgPropertiesCopier.cs b/itext/itext.kernel/itext/kernel/pdf/OcgPropertiesCopier.cs index 2d88e53a97..03f284e0fd 100644 --- a/itext/itext.kernel/itext/kernel/pdf/OcgPropertiesCopier.cs +++ b/itext/itext.kernel/itext/kernel/pdf/OcgPropertiesCopier.cs @@ -26,7 +26,9 @@ You should have received a copy of the GNU Affero General Public License using iText.Commons; using iText.Commons.Utils; using iText.IO.Font; +using iText.Kernel.Logs; using iText.Kernel.Pdf.Annot; +using iText.Kernel.Pdf.Layer; namespace iText.Kernel.Pdf { internal sealed class OcgPropertiesCopier { @@ -251,19 +253,20 @@ private static void CopyDDictionary(ICollection fromOcgsTo toOcProperties.Put(PdfName.D, new PdfDictionary()); } PdfDictionary toDDict = toOcProperties.GetAsDictionary(PdfName.D); - // The Name field is not copied because it will be given when flushing the PdfOCProperties + iText.Kernel.Pdf.OcgPropertiesCopier.CopyDStringField(PdfName.Name, fromDDict, toDDict); // Delete the Creator field because the D dictionary are changing toDDict.Remove(PdfName.Creator); - // The BaseState field is not copied because for dictionary D BaseState should have the value ON, which is the default + iText.Kernel.Pdf.OcgPropertiesCopier.CopyDNameField(PdfName.BaseState, fromDDict, toDDict); iText.Kernel.Pdf.OcgPropertiesCopier.CopyDArrayField(PdfName.ON, fromOcgsToCopy, fromDDict, toDDict, toDocument ); iText.Kernel.Pdf.OcgPropertiesCopier.CopyDArrayField(PdfName.OFF, fromOcgsToCopy, fromDDict, toDDict, toDocument ); - // The Intent field is not copied because for dictionary D Intent should have the value View, which is the default + iText.Kernel.Pdf.OcgPropertiesCopier.CopyDNameField(PdfName.Intent, fromDDict, toDDict); // The AS field is not copied because it will be given when flushing the PdfOCProperties iText.Kernel.Pdf.OcgPropertiesCopier.CopyDArrayField(PdfName.Order, fromOcgsToCopy, fromDDict, toDDict, toDocument ); - // The ListModel field is not copied because it only affects the visual presentation of the layers + // The ListMode field is copied, but it only affects the visual presentation of the layers + iText.Kernel.Pdf.OcgPropertiesCopier.CopyDNameField(PdfName.ListMode, fromDDict, toDDict); iText.Kernel.Pdf.OcgPropertiesCopier.CopyDArrayField(PdfName.RBGroups, fromOcgsToCopy, fromDDict, toDDict, toDocument); iText.Kernel.Pdf.OcgPropertiesCopier.CopyDArrayField(PdfName.Locked, fromOcgsToCopy, fromDDict, toDDict, toDocument @@ -278,6 +281,38 @@ private static void AttemptToAddObjectToArray(ICollection } } + private static void CopyDNameField(PdfName fieldToCopy, PdfDictionary fromDict, PdfDictionary toDict) { + PdfName fromName = fromDict.GetAsName(fieldToCopy); + if (fromName == null || toDict.GetAsName(fieldToCopy) != null) { + return; + } + if (PdfOCProperties.CheckDDictonaryFieldValue(fieldToCopy, fromName)) { + toDict.Put(fieldToCopy, fromName); + } + else { + ILogger logger = ITextLogManager.GetLogger(typeof(iText.Kernel.Pdf.OcgPropertiesCopier)); + String warnText = MessageFormatUtil.Format(KernelLogMessageConstant.INVALID_DDICTIONARY_FIELD_VALUE, fieldToCopy + , fromName); + logger.LogWarning(warnText); + } + } + + private static void CopyDStringField(PdfName fieldToCopy, PdfDictionary fromDict, PdfDictionary toDict) { + PdfString fromString = fromDict.GetAsString(fieldToCopy); + if (fromString == null || toDict.GetAsString(fieldToCopy) != null) { + return; + } + if (PdfOCProperties.CheckDDictonaryFieldValue(fieldToCopy, fromString)) { + toDict.Put(fieldToCopy, fromString); + } + else { + ILogger logger = ITextLogManager.GetLogger(typeof(iText.Kernel.Pdf.OcgPropertiesCopier)); + String warnText = MessageFormatUtil.Format(KernelLogMessageConstant.INVALID_DDICTIONARY_FIELD_VALUE, fieldToCopy + , fromString); + logger.LogWarning(warnText); + } + } + private static void CopyDArrayField(PdfName fieldToCopy, ICollection fromOcgsToCopy, PdfDictionary fromDict, PdfDictionary toDict, PdfDocument toDocument) { if (fromDict.GetAsArray(fieldToCopy) == null) { diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfCatalog.cs b/itext/itext.kernel/itext/kernel/pdf/PdfCatalog.cs index 48fdd6c46c..bc49dc8312 100644 --- a/itext/itext.kernel/itext/kernel/pdf/PdfCatalog.cs +++ b/itext/itext.kernel/itext/kernel/pdf/PdfCatalog.cs @@ -80,6 +80,8 @@ public class PdfCatalog : PdfObjectWrapper { // If this flag is false all outline operations will be ignored private bool outlineMode; + private bool ocgCopied = false; + /// /// Create /// @@ -494,7 +496,11 @@ public virtual iText.Kernel.Pdf.PdfCatalog Remove(PdfName key) { /// /// boolean indicating if the dictionary needs to be reconstructed protected internal virtual bool IsOCPropertiesMayHaveChanged() { - return ocProperties != null; + return ocProperties != null || ocgCopied; + } + + internal virtual void SetOcgCopied(bool ocgCopied) { + this.ocgCopied = ocgCopied; } internal virtual PdfPagesTree GetPageTree() { diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs b/itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs index 432f9d9658..4482f2e945 100644 --- a/itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs +++ b/itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs @@ -1243,6 +1243,7 @@ public virtual IList CopyPagesTo(IList pagesToCopy, iText.Kernel.P // Copying OCGs should go after copying LinkAnnotations if (GetCatalog() != null && GetCatalog().GetPdfObject().GetAsDictionary(PdfName.OCProperties) != null) { OcgPropertiesCopier.CopyOCGProperties(this, toDocument, page2page); + toDocument.GetCatalog().SetOcgCopied(true); } // It's important to copy tag structure after link annotations were copied, because object content items in tag // structure are not copied in case if their's OBJ key is annotation and doesn't contain /P entry. diff --git a/itext/itext.kernel/itext/kernel/pdf/layer/PdfOCProperties.cs b/itext/itext.kernel/itext/kernel/pdf/layer/PdfOCProperties.cs index 09d61c92ba..4ffb5743b5 100644 --- a/itext/itext.kernel/itext/kernel/pdf/layer/PdfOCProperties.cs +++ b/itext/itext.kernel/itext/kernel/pdf/layer/PdfOCProperties.cs @@ -22,7 +22,11 @@ You should have received a copy of the GNU Affero General Public License */ using System; using System.Collections.Generic; +using Microsoft.Extensions.Logging; +using iText.Commons; +using iText.Commons.Utils; using iText.IO.Font; +using iText.Kernel.Logs; using iText.Kernel.Pdf; namespace iText.Kernel.Pdf.Layer { @@ -131,18 +135,24 @@ public virtual PdfObject FillDictionary(bool removeNonDocumentOcgs) { } } GetPdfObject().Put(PdfName.OCGs, gr); - // Save radio groups. - PdfArray rbGroups = null; - PdfDictionary d = GetPdfObject().GetAsDictionary(PdfName.D); - if (d != null) { - rbGroups = d.GetAsArray(PdfName.RBGroups); - } - d = new PdfDictionary(); - if (rbGroups != null) { - d.Put(PdfName.RBGroups, rbGroups); - } - d.Put(PdfName.Name, new PdfString(CreateUniqueName(), PdfEncodings.UNICODE_BIG)); - GetPdfObject().Put(PdfName.D, d); + PdfDictionary filledDDictionary = new PdfDictionary(); + // Save radio groups,Name,BaseState,Intent,ListMode + PdfDictionary dDictionary = GetPdfObject().GetAsDictionary(PdfName.D); + if (dDictionary != null) { + iText.Kernel.Pdf.Layer.PdfOCProperties.CopyDDictionaryField(PdfName.RBGroups, dDictionary, filledDDictionary + ); + iText.Kernel.Pdf.Layer.PdfOCProperties.CopyDDictionaryField(PdfName.Name, dDictionary, filledDDictionary); + iText.Kernel.Pdf.Layer.PdfOCProperties.CopyDDictionaryField(PdfName.BaseState, dDictionary, filledDDictionary + ); + iText.Kernel.Pdf.Layer.PdfOCProperties.CopyDDictionaryField(PdfName.Intent, dDictionary, filledDDictionary + ); + iText.Kernel.Pdf.Layer.PdfOCProperties.CopyDDictionaryField(PdfName.ListMode, dDictionary, filledDDictionary + ); + } + if (filledDDictionary.Get(PdfName.Name) == null) { + filledDDictionary.Put(PdfName.Name, new PdfString(CreateUniqueName(), PdfEncodings.UNICODE_BIG)); + } + GetPdfObject().Put(PdfName.D, filledDDictionary); IList docOrder = new List(layers); for (int i = 0; i < docOrder.Count; i++) { PdfLayer layer = docOrder[i]; @@ -156,7 +166,7 @@ public virtual PdfObject FillDictionary(bool removeNonDocumentOcgs) { PdfLayer layer = (PdfLayer)element; GetOCGOrder(order, layer); } - d.Put(PdfName.Order, order); + filledDDictionary.Put(PdfName.Order, order); PdfArray off = new PdfArray(); foreach (Object element in layers) { PdfLayer layer = (PdfLayer)element; @@ -165,10 +175,7 @@ public virtual PdfObject FillDictionary(bool removeNonDocumentOcgs) { } } if (off.Size() > 0) { - d.Put(PdfName.OFF, off); - } - else { - d.Remove(PdfName.OFF); + filledDDictionary.Put(PdfName.OFF, off); } PdfArray locked = new PdfArray(); foreach (PdfLayer layer in layers) { @@ -177,12 +184,8 @@ public virtual PdfObject FillDictionary(bool removeNonDocumentOcgs) { } } if (locked.Size() > 0) { - d.Put(PdfName.Locked, locked); + filledDDictionary.Put(PdfName.Locked, locked); } - else { - d.Remove(PdfName.Locked); - } - d.Remove(PdfName.AS); AddASEvent(PdfName.View, PdfName.Zoom); AddASEvent(PdfName.View, PdfName.View); AddASEvent(PdfName.Print, PdfName.Print); @@ -193,6 +196,27 @@ public virtual PdfObject FillDictionary(bool removeNonDocumentOcgs) { return GetPdfObject(); } + /// + /// Checks if optional content group default configuration dictionary field value matches + /// the required value for this field, if one exists. + /// + /// default configuration dictionary field. + /// value of that field. + /// boolean indicating if field meets requirement. + public static bool CheckDDictonaryFieldValue(PdfName field, PdfObject value) { + // dictionary D BaseState should have the value ON + if (PdfName.BaseState.Equals(field) && !PdfName.ON.Equals(value)) { + return false; + } + else { + //for dictionary D Intent should have the value View + if (PdfName.Intent.Equals(field) && !PdfName.View.Equals(value)) { + return false; + } + } + return true; + } + public override void Flush() { FillDictionary(); base.Flush(); @@ -266,6 +290,22 @@ private static void GetOCGOrder(PdfArray order, PdfLayer layer) { } } + private static void CopyDDictionaryField(PdfName fieldToAdd, PdfDictionary fromDictionary, PdfDictionary toDictionary + ) { + PdfObject value = fromDictionary.Get(fieldToAdd); + if (value != null) { + if (iText.Kernel.Pdf.Layer.PdfOCProperties.CheckDDictonaryFieldValue(fieldToAdd, value)) { + toDictionary.Put(fieldToAdd, value); + } + else { + ILogger logger = ITextLogManager.GetLogger(typeof(iText.Kernel.Pdf.Layer.PdfOCProperties)); + String warnText = MessageFormatUtil.Format(KernelLogMessageConstant.INVALID_DDICTIONARY_FIELD_VALUE, fieldToAdd + , value); + logger.LogWarning(warnText); + } + } + } + private void RemoveNotRegisteredOcgs() { PdfDictionary dDict = GetPdfObject().GetAsDictionary(PdfName.D); PdfDictionary ocProperties = this.GetDocument().GetCatalog().GetPdfObject().GetAsDictionary(PdfName.OCProperties diff --git a/port-hash b/port-hash index 6fc845e2ee..1a36faf6e3 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -0ecc4cd397ba4046902f2a0685b2aa35e1c16d89 +abe3f098b9d6dedcab048715f32f1de25b60e65c