Skip to content

Commit

Permalink
Remove Duplicate OCProperties
Browse files Browse the repository at this point in the history
DEVSIX-8396

Autoported commit.
Original commit hash: [1ee19dc92]
  • Loading branch information
Alexander Pliushchou authored and iText-CI committed Jul 28, 2024
1 parent 839b135 commit de6e4ed
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 3 deletions.
56 changes: 56 additions & 0 deletions itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfDocumentTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,62 @@ public virtual void GetDefaultConformanceLevelTest() {
NUnit.Framework.Assert.IsNull(document.GetConformanceLevel());
}

//TODO DEVSIX-8490 remove this test when implemented
[NUnit.Framework.Test]
[LogMessage(KernelLogMessageConstant.DUPLICATE_ENTRIES_IN_ORDER_ARRAY_REMOVED)]
public virtual void RemoveDuplicatesInOrderArrayTest() {
String inputPdf = "removeDuplicatesInOrderArray.pdf";
String outputPdf = "removedDuplicateInOrderArray.pdf";
PdfDocument doc = new PdfDocument(new PdfReader(SOURCE_FOLDER + inputPdf), CompareTool.CreateTestPdfWriter
(DESTINATION_FOLDER + outputPdf));
//Need to update OCProperties
doc.GetCatalog().GetOCProperties(false);
doc.Close();
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(DESTINATION_FOLDER + outputPdf, SOURCE_FOLDER
+ "cmp_" + outputPdf, DESTINATION_FOLDER));
}

//TODO DEVSIX-8490 remove this test when implemented
[NUnit.Framework.Test]
[LogMessage(KernelLogMessageConstant.DUPLICATE_ENTRIES_IN_ORDER_ARRAY_REMOVED)]
public virtual void RemoveNestedDuplicatesInOrderArrayTest() {
String inputPdf = "removeNestedDuplicatesInOrderArray.pdf";
String outputPdf = "removedNestedDuplicatesInOrderArray.pdf";
PdfDocument doc = new PdfDocument(new PdfReader(SOURCE_FOLDER + inputPdf), new PdfWriter(DESTINATION_FOLDER
+ outputPdf));
//Need to update OCProperties
doc.GetCatalog().GetOCProperties(false);
doc.Close();
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(DESTINATION_FOLDER + outputPdf, SOURCE_FOLDER
+ "cmp_" + outputPdf, DESTINATION_FOLDER));
}

//TODO DEVSIX-8490 remove this test when implemented
[NUnit.Framework.Test]
public virtual void RemoveDuplicatesHasChildInOrderArrayTest() {
String inputPdf = "removeDuplicatesHasChildInOrderArray.pdf";
String outputPdf = "removedDuplicatesHasChildInOrderArray.pdf";
PdfDocument doc = new PdfDocument(new PdfReader(SOURCE_FOLDER + inputPdf), CompareTool.CreateTestPdfWriter
(DESTINATION_FOLDER + outputPdf));
PdfCatalog catalog = doc.GetCatalog();
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => catalog.GetOCProperties(false));
NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(KernelExceptionMessageConstant.UNABLE_TO_REMOVE_DUPLICATE_LAYER
, "4 0 R"), e.Message);
}

//TODO DEVSIX-8490 remove this test when implemented
[NUnit.Framework.Test]
public virtual void RemoveNestedDuplicatesHasChildInOrderArrayTest() {
String inputPdf = "removeNestedDuplicatesHasChildInOrderArray.pdf";
String outputPdf = "removedNestedDuplicatesHasChildInOrderArray.pdf";
PdfDocument doc = new PdfDocument(new PdfReader(SOURCE_FOLDER + inputPdf), CompareTool.CreateTestPdfWriter
(DESTINATION_FOLDER + outputPdf));
PdfCatalog catalog = doc.GetCatalog();
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => catalog.GetOCProperties(false));
NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(KernelExceptionMessageConstant.UNABLE_TO_REMOVE_DUPLICATE_LAYER
, "27 0 R"), e.Message);
}

private class IgnoreTagStructurePdfDocument : PdfDocument {
//\cond DO_NOT_DOCUMENT
internal IgnoreTagStructurePdfDocument(PdfReader reader)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ You should have received a copy of the GNU Affero General Public License
using System.Collections.Generic;
using iText.Commons.Utils;
using iText.IO.Font.Constants;
using iText.IO.Source;
using iText.Kernel.Exceptions;
using iText.Kernel.Font;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
Expand Down Expand Up @@ -354,5 +356,22 @@ public virtual void TestInStamperMode2() {
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(destinationFolder + "output_layered.pdf",
sourceFolder + "cmp_output_layered.pdf", destinationFolder, "diff"));
}

//TODO DEVSIX-8490 remove this test when implemented
[NUnit.Framework.Test]
public virtual void AddSecondParentlayerTest() {
using (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
using (PdfDocument doc = new PdfDocument(new PdfWriter(outputStream))) {
PdfLayer childLayer = new PdfLayer("childLayer", doc);
PdfLayer parentLayer1 = new PdfLayer("firstParentLayer", doc);
PdfLayer parentLayer2 = new PdfLayer("secondParentLayer", doc);
parentLayer1.AddChild(childLayer);
PdfIndirectReference @ref = childLayer.GetIndirectReference();
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => parentLayer2.AddChild(childLayer));
NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(KernelExceptionMessageConstant.UNABLE_TO_ADD_SECOND_PARENT_LAYER
, @ref.ToString()), e.Message);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using System.IO;
using iText.Commons.Utils;
using iText.IO.Source;
using iText.Kernel.Exceptions;
using iText.Kernel.Pdf;

namespace iText.Kernel.Pdf.Layer {
[NUnit.Framework.Category("UnitTest")]
public class PdfOCPropertiesUnitTest {
//TODO DEVSIX-8490 remove this test when implemented
[NUnit.Framework.Test]
public virtual void RemoveOrderDuplicatesTest() {
byte[] docBytes;
using (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
using (PdfDocument document = new PdfDocument(new PdfWriter(outputStream))) {
PdfDictionary ocgDic = new PdfDictionary();
ocgDic.MakeIndirect(document);
PdfArray orderArray = new PdfArray();
for (int i = 0; i < 3; i++) {
orderArray.Add(ocgDic);
}
PdfDictionary ocgDic2 = new PdfDictionary();
ocgDic.MakeIndirect(document);
for (int i = 0; i < 3; i++) {
PdfArray layerArray = new PdfArray();
layerArray.Add(new PdfString("layerName" + i));
layerArray.Add(ocgDic2);
orderArray.Add(layerArray);
}
PdfDictionary DDictionary = new PdfDictionary();
DDictionary.Put(PdfName.Order, orderArray);
PdfArray OCGsArray = new PdfArray();
OCGsArray.Add(ocgDic);
OCGsArray.Add(ocgDic2);
PdfDictionary OCPropertiesDic = new PdfDictionary();
OCPropertiesDic.Put(PdfName.D, DDictionary);
OCPropertiesDic.Put(PdfName.OCGs, OCGsArray);
document.GetCatalog().GetPdfObject().Put(PdfName.OCProperties, OCPropertiesDic);
document.GetCatalog().GetOCProperties(false);
}
docBytes = outputStream.ToArray();
}
using (PdfDocument docReopen = new PdfDocument(new PdfReader(new MemoryStream(docBytes)))) {
PdfArray resultArray = docReopen.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.OCProperties).GetAsDictionary
(PdfName.D).GetAsArray(PdfName.Order);
NUnit.Framework.Assert.AreEqual(2, resultArray.Size());
}
}

//TODO DEVSIX-8490 remove this test when implemented
[NUnit.Framework.Test]
public virtual void RemoveOrderDuplicateHasChildTest() {
using (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
using (PdfDocument document = new PdfDocument(new PdfWriter(outputStream))) {
PdfDictionary ocgDic = new PdfDictionary();
PdfDictionary ocgDicChild1 = new PdfDictionary();
PdfDictionary ocgDicChild2 = new PdfDictionary();
ocgDic.MakeIndirect(document);
PdfArray orderArray = new PdfArray();
PdfArray childArray1 = new PdfArray();
childArray1.Add(ocgDicChild1);
PdfArray childArray2 = new PdfArray();
childArray2.Add(ocgDicChild2);
orderArray.Add(ocgDic);
orderArray.Add(childArray1);
orderArray.Add(ocgDic);
orderArray.Add(childArray2);
PdfDictionary DDictionary = new PdfDictionary();
DDictionary.Put(PdfName.Order, orderArray);
PdfArray OCGsArray = new PdfArray();
OCGsArray.Add(ocgDic);
OCGsArray.Add(ocgDicChild1);
OCGsArray.Add(ocgDicChild2);
PdfDictionary OCPropertiesDic = new PdfDictionary();
OCPropertiesDic.Put(PdfName.D, DDictionary);
OCPropertiesDic.Put(PdfName.OCGs, OCGsArray);
document.GetCatalog().GetPdfObject().Put(PdfName.OCProperties, OCPropertiesDic);
PdfIndirectReference @ref = ocgDic.GetIndirectReference();
PdfCatalog catalog = document.GetCatalog();
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => catalog.GetOCProperties(false));
NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(KernelExceptionMessageConstant.UNABLE_TO_REMOVE_DUPLICATE_LAYER
, @ref.ToString()), e.Message);
}
}
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,12 @@ public const String WHEN_ADDING_OBJECT_REFERENCE_TO_THE_TAG_TREE_IT_MUST_BE_CONN

public const String INVALID_OBJECT_STREAM_NUMBER = "Unable to read object {0} with object stream " + "number {1} and index {2} from object stream.";

//TODO DEVSIX-8490 remove this exception message when implemented
public const String UNABLE_TO_ADD_SECOND_PARENT_LAYER = "Unable to add second parent layer to " + "{0} ocg layer";

//TODO DEVSIX-8490 remove this exception message when implemented
public const String UNABLE_TO_REMOVE_DUPLICATE_LAYER = "Unable to remove duplicated layer {0} " + "because it has child layers.";

private KernelExceptionMessageConstant() {
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ public sealed class KernelLogMessageConstant {

public const String XOBJECT_STRUCT_PARENT_INDEX_MISSED_AND_RECREATED = "XObject has no StructParents index in its stream, so index is recreated";

//TODO DEVSIX-8490 remove this log message when implemented
public const String DUPLICATE_ENTRIES_IN_ORDER_ARRAY_REMOVED = "Duplicated entries in order array are " +
"removed";

private KernelLogMessageConstant() {
}
//Private constructor will prevent the instantiation of this class directly
Expand Down
6 changes: 5 additions & 1 deletion itext/itext.kernel/itext/kernel/pdf/layer/PdfLayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ You should have received a copy of the GNU Affero General Public License
using System.Collections.Generic;
using iText.Commons.Utils;
using iText.IO.Font;
using iText.Kernel.Exceptions;
using iText.Kernel.Pdf;

namespace iText.Kernel.Pdf.Layer {
Expand Down Expand Up @@ -114,8 +115,11 @@ public static void AddOCGRadioGroup(PdfDocument document, IList<iText.Kernel.Pdf
/// <remarks>Adds a child layer. Nested layers can only have one parent.</remarks>
/// <param name="childLayer">the child layer</param>
public virtual void AddChild(iText.Kernel.Pdf.Layer.PdfLayer childLayer) {
//TODO DEVSIX-8490 implement multiple parent support
if (childLayer.parent != null) {
throw new ArgumentException("Illegal argument: childLayer");
PdfIndirectReference @ref = childLayer.GetIndirectReference();
throw new PdfException(MessageFormatUtil.Format(KernelExceptionMessageConstant.UNABLE_TO_ADD_SECOND_PARENT_LAYER
, @ref.ToString()));
}
childLayer.parent = this;
if (children == null) {
Expand Down
34 changes: 33 additions & 1 deletion itext/itext.kernel/itext/kernel/pdf/layer/PdfOCProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ 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.Exceptions;
using iText.Kernel.Logs;
using iText.Kernel.Pdf;

Expand All @@ -51,6 +52,12 @@ public class PdfOCProperties : PdfObjectWrapper<PdfDictionary> {

private IList<PdfLayer> layers = new List<PdfLayer>();

//TODO DEVSIX-8490 remove this field when implemented
private ICollection<PdfIndirectReference> references;

//TODO DEVSIX-8490 remove this field when implemented
private bool isDuplicateRemoved;

/// <summary>Creates a new PdfOCProperties instance.</summary>
/// <param name="document">the document the optional content belongs to</param>
public PdfOCProperties(PdfDocument document)
Expand Down Expand Up @@ -406,7 +413,14 @@ private void ReadLayersFromDictionary() {
}
PdfArray orderArray = d.GetAsArray(PdfName.Order);
if (orderArray != null && !orderArray.IsEmpty()) {
references = new HashSet<PdfIndirectReference>();
isDuplicateRemoved = false;
ReadOrderFromDictionary(null, orderArray, layerMap);
//TODO DEVSIX-8490 remove this check when implemented
if (isDuplicateRemoved) {
ILogger logger = ITextLogManager.GetLogger(typeof(iText.Kernel.Pdf.Layer.PdfOCProperties));
logger.LogWarning(KernelLogMessageConstant.DUPLICATE_ENTRIES_IN_ORDER_ARRAY_REMOVED);
}
}
}
// Add the layers which should not be displayed on the panel to the order list
Expand All @@ -424,7 +438,25 @@ private void ReadOrderFromDictionary(PdfLayer parent, PdfArray orderArray, IDict
PdfObject item = orderArray.Get(i);
if (item.GetObjectType() == PdfObject.DICTIONARY) {
PdfLayer layer = layerMap.Get(item.GetIndirectReference());
if (layer != null) {
if (layer == null) {
continue;
}
//TODO DEVSIX-8490 remove this check and it statement when implemented
if (references.Contains(layer.GetIndirectReference())) {
//We want to check if this duplicate layer has childLayers, if it has - throw an exception,
// else just don't add this layer.
if (i + 1 < orderArray.Size() && orderArray.Get(i + 1).GetObjectType() == PdfObject.ARRAY) {
PdfArray nextArray = orderArray.GetAsArray(i + 1);
if (nextArray.Size() > 0 && nextArray.Get(0).GetObjectType() != PdfObject.STRING) {
PdfIndirectReference @ref = layer.GetIndirectReference();
throw new PdfException(MessageFormatUtil.Format(KernelExceptionMessageConstant.UNABLE_TO_REMOVE_DUPLICATE_LAYER
, @ref.ToString()));
}
}
isDuplicateRemoved = true;
}
else {
references.Add(layer.GetIndirectReference());
layers.Add(layer);
layer.onPanel = true;
if (parent != null) {
Expand Down
2 changes: 1 addition & 1 deletion port-hash
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cd91477a6b5dcb768f827dfa4d1083fecb2c8f52
1ee19dc92c5f07f9f932d3ffdf0748616ea1b8c3

0 comments on commit de6e4ed

Please sign in to comment.