Skip to content

Commit 790949b

Browse files
carl-di-ortusdmitry.radchuk
authored andcommitted
SUP-34435 Save XMP metadata in canonical format for PDF/A documents.
Closes .NET GitHub PR 22 DEVSIX-6355
1 parent 5757673 commit 790949b

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

itext.tests/itext.pdfa.tests/itext/pdfa/PdfAXmpTest.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ source product.
4444
using System.IO;
4545
using iText.Kernel.Pdf;
4646
using iText.Kernel.Utils;
47+
using iText.Kernel.XMP;
48+
using iText.Kernel.XMP.Options;
4749
using iText.Test;
4850

4951
namespace iText.Pdfa {
@@ -95,5 +97,35 @@ public virtual void KeywordsInfoTestPdfA2b() {
9597
NUnit.Framework.Assert.IsNull(ct.CompareDocumentInfo(outFile, cmpFile));
9698
NUnit.Framework.Assert.IsNull(ct.CompareXmp(outFile, cmpFile, true));
9799
}
100+
101+
[NUnit.Framework.Test]
102+
public virtual void SaveAndReadDocumentWithCanonicalXmpMetadata()
103+
{
104+
String outFile = destinationFolder + "saveAndReadDocumentWithCanonicalXmpMetadata.pdf";
105+
PdfAConformanceLevel conformanceLevel = PdfAConformanceLevel.PDF_A_2B;
106+
Stream @is = new FileStream(sourceFolder + "sRGB Color Space Profile.icm", FileMode.Open, FileAccess.Read);
107+
PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1"
108+
, @is);
109+
PdfADocument doc = new PdfADocument(new PdfWriter(outFile), conformanceLevel, outputIntent);
110+
doc.AddNewPage();
111+
XMPMeta xmp = XMPMetaFactory.Create();
112+
xmp.SetProperty(XMPConst.NS_PDFA_ID, XMPConst.PART, conformanceLevel.GetPart(), new PropertyOptions().SetSchemaNode(true));
113+
xmp.SetProperty(XMPConst.NS_PDFA_ID, XMPConst.CONFORMANCE, conformanceLevel.GetConformance(), new PropertyOptions().SetSchemaNode(true));
114+
var options = new SerializeOptions().SetUseCanonicalFormat(true).SetUseCompactFormat(false);
115+
doc.SetXmpMetadata(xmp, options);
116+
doc.SetTagged();
117+
doc.Close();
118+
PdfReader reader = new PdfReader(outFile);
119+
PdfDocument resultDoc = new PdfDocument(reader);
120+
PdfAConformanceLevel conformanceLevelResult = resultDoc.GetReader().GetPdfAConformanceLevel();
121+
NUnit.Framework.Assert.IsNotNull(conformanceLevelResult);
122+
NUnit.Framework.Assert.AreEqual(conformanceLevel.GetConformance(), conformanceLevelResult.GetConformance());
123+
NUnit.Framework.Assert.AreEqual(conformanceLevel.GetPart(), conformanceLevelResult.GetPart());
124+
byte[] xmpResultBytes = resultDoc.GetXmpMetadata();
125+
resultDoc.Close();
126+
NUnit.Framework.Assert.IsNotNull(xmpResultBytes);
127+
XMPMeta xmpResult = XMPMetaFactory.ParseFromBuffer(xmpResultBytes);
128+
NUnit.Framework.Assert.IsNotNull(xmpResult);
129+
}
98130
}
99131
}

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ public class PdfDocument : IEventDispatcher, IDisposable {
125125

126126
protected internal FingerPrint fingerPrint;
127127

128+
protected internal SerializeOptions serializeOptions = new SerializeOptions();
129+
128130
protected internal readonly StampingProperties properties;
129131

130132
protected internal PdfStructTreeRoot structTreeRoot;
@@ -264,16 +266,17 @@ protected internal virtual void SetXmpMetadata(byte[] xmpMetadata) {
264266
}
265267

266268
/// <summary>Sets the XMP Metadata.</summary>
269+
/// <remarks>SerializeOptions are saved for the lifetime of PdfDocument.</remarks>
267270
/// <param name="xmpMeta">the xmpMetadata to set</param>
268-
/// <param name="serializeOptions">serialization options</param>
269-
public virtual void SetXmpMetadata(XMPMeta xmpMeta, SerializeOptions serializeOptions) {
270-
SetXmpMetadata(XMPMetaFactory.SerializeToBuffer(xmpMeta, serializeOptions));
271+
/// <param name="options">serialization options</param>
272+
public virtual void SetXmpMetadata(XMPMeta xmpMeta, SerializeOptions options) {
273+
serializeOptions = options;
274+
SetXmpMetadata(XMPMetaFactory.SerializeToBuffer(xmpMeta, options));
271275
}
272276

273277
/// <summary>Sets the XMP Metadata.</summary>
274278
/// <param name="xmpMeta">the xmpMetadata to set</param>
275279
public virtual void SetXmpMetadata(XMPMeta xmpMeta) {
276-
SerializeOptions serializeOptions = new SerializeOptions();
277280
serializeOptions.SetPadding(2000);
278281
SetXmpMetadata(xmpMeta, serializeOptions);
279282
}
@@ -1919,6 +1922,13 @@ public virtual SequenceId GetDocumentIdWrapper() {
19191922
return documentId;
19201923
}
19211924

1925+
/// <summary>Sets a persistent XMP metadata serialization options.</summary>
1926+
/// <param name="options"><see cref="iText.Kernel.XMP.Options.SerializeOptions"/>.</param>
1927+
public virtual void SetSerializeOptions(SerializeOptions options)
1928+
{
1929+
serializeOptions = options;
1930+
}
1931+
19221932
/// <summary>Gets list of indirect references.</summary>
19231933
/// <returns>list of indirect references.</returns>
19241934
internal virtual PdfXrefTable GetXref() {

itext/itext.kernel/itext/kernel/xmp/impl/XMPSerializerRdf.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,10 @@ private void DeclareNamespace(String prefix, String @namespace, ICollection<Stri
803803
return;
804804
}
805805
}
806+
if (string.IsNullOrEmpty(prefix))
807+
{
808+
return;
809+
}
806810
if (!usedPrefixes.Contains(prefix))
807811
{
808812
WriteNewline();

0 commit comments

Comments
 (0)