diff --git a/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfUAConformanceTest.cs b/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfUAConformanceTest.cs
new file mode 100644
index 000000000..2593dc5fc
--- /dev/null
+++ b/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfUAConformanceTest.cs
@@ -0,0 +1,54 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2025 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using iText.Kernel.XMP;
+using iText.Kernel.XMP.Impl;
+using iText.Test;
+
+namespace iText.Kernel.Pdf {
+ [NUnit.Framework.Category("UnitTest")]
+ public class PdfUAConformanceTest : ExtendedITextTest {
+ [NUnit.Framework.Test]
+ public virtual void GetUA1ConformanceTest() {
+ XMPMeta meta = new XMPMetaImpl();
+ meta.SetProperty(XMPConst.NS_PDFUA_ID, XMPConst.PART, "1");
+ PdfConformance level = PdfConformance.GetConformance(meta);
+ NUnit.Framework.Assert.AreEqual(PdfUAConformance.PDF_UA_1, level.GetUAConformance());
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetUA2ConformanceTest() {
+ XMPMeta meta = new XMPMetaImpl();
+ meta.SetProperty(XMPConst.NS_PDFUA_ID, XMPConst.PART, "2");
+ PdfConformance level = PdfConformance.GetConformance(meta);
+ NUnit.Framework.Assert.AreEqual(PdfUAConformance.PDF_UA_2, level.GetUAConformance());
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetUAConformanceNullTest() {
+ XMPMeta meta = new XMPMetaImpl();
+ meta.SetProperty(XMPConst.NS_PDFUA_ID, XMPConst.PART, "3");
+ PdfConformance level = PdfConformance.GetConformance(meta);
+ NUnit.Framework.Assert.IsNull(level.GetUAConformance());
+ }
+ }
+}
diff --git a/itext.tests/itext.pdfua.tests/itext/pdfua/PdfUADocumentTest.cs b/itext.tests/itext.pdfua.tests/itext/pdfua/PdfUADocumentTest.cs
index f67ec0fc3..3f0be2c23 100644
--- a/itext.tests/itext.pdfua.tests/itext/pdfua/PdfUADocumentTest.cs
+++ b/itext.tests/itext.pdfua.tests/itext/pdfua/PdfUADocumentTest.cs
@@ -36,11 +36,19 @@ public class PdfUADocumentTest : ExtendedITextTest {
[NUnit.Framework.Test]
[LogMessage(PdfUALogMessageConstants.PDF_TO_PDF_UA_CONVERSION_IS_NOT_SUPPORTED, LogLevel = LogLevelConstants
.WARN)]
- public virtual void OpenNotUaDocumentTest() {
+ public virtual void OpenNotUa1DocumentTest() {
NUnit.Framework.Assert.DoesNotThrow(() => new PdfUADocument(new PdfReader(SOURCE_FOLDER + "usualPdf.pdf"),
new PdfWriter(new MemoryStream()), new PdfUAConfig(PdfUAConformance.PDF_UA_1, "simple doc", "eng")));
}
+ [NUnit.Framework.Test]
+ [LogMessage(PdfUALogMessageConstants.PDF_TO_PDF_UA_CONVERSION_IS_NOT_SUPPORTED, LogLevel = LogLevelConstants
+ .WARN)]
+ public virtual void OpenNotUa2DocumentTest() {
+ NUnit.Framework.Assert.DoesNotThrow(() => new PdfUADocument(new PdfReader(SOURCE_FOLDER + "usualPdf.pdf"),
+ new PdfWriter(new MemoryStream()), new PdfUAConfig(PdfUAConformance.PDF_UA_2, "simple doc", "eng")));
+ }
+
[NUnit.Framework.Test]
[LogMessage(PdfUALogMessageConstants.WRITER_PROPERTIES_PDF_VERSION_WAS_OVERRIDDEN, LogLevel = LogLevelConstants
.WARN)]
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfConformance.cs b/itext/itext.kernel/itext/kernel/pdf/PdfConformance.cs
index 5f4ec72bc..ee390a0ce 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfConformance.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfConformance.cs
@@ -66,6 +66,9 @@ public class PdfConformance {
public static readonly iText.Kernel.Pdf.PdfConformance PDF_UA_1 = new iText.Kernel.Pdf.PdfConformance(PdfUAConformance
.PDF_UA_1);
+ public static readonly iText.Kernel.Pdf.PdfConformance PDF_UA_2 = new iText.Kernel.Pdf.PdfConformance(PdfUAConformance
+ .PDF_UA_2);
+
public static readonly iText.Kernel.Pdf.PdfConformance PDF_NONE_CONFORMANCE = new iText.Kernel.Pdf.PdfConformance
();
@@ -349,6 +352,9 @@ private static PdfUAConformance GetUAConformance(String part) {
if ("1".Equals(part)) {
return PdfUAConformance.PDF_UA_1;
}
+ if ("2".Equals(part)) {
+ return PdfUAConformance.PDF_UA_2;
+ }
return null;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfUAConformance.cs b/itext/itext.kernel/itext/kernel/pdf/PdfUAConformance.cs
index 66ab8d8c3..253fcb0cc 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfUAConformance.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfUAConformance.cs
@@ -33,6 +33,10 @@ public sealed class PdfUAConformance {
public static readonly iText.Kernel.Pdf.PdfUAConformance PDF_UA_1 = new iText.Kernel.Pdf.PdfUAConformance(
"1");
+ /// PDF/UA-2 conformance
+ public static readonly iText.Kernel.Pdf.PdfUAConformance PDF_UA_2 = new iText.Kernel.Pdf.PdfUAConformance(
+ "2");
+
private readonly String part;
//\cond DO_NOT_DOCUMENT
diff --git a/itext/itext.pdfua/itext/pdfua/PdfUADocument.cs b/itext/itext.pdfua/itext/pdfua/PdfUADocument.cs
index 58598240d..53d3b6ff1 100644
--- a/itext/itext.pdfua/itext/pdfua/PdfUADocument.cs
+++ b/itext/itext.pdfua/itext/pdfua/PdfUADocument.cs
@@ -20,12 +20,14 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
+using System;
using Microsoft.Extensions.Logging;
using iText.Commons;
using iText.Commons.Utils;
using iText.Kernel.Pdf;
using iText.Kernel.Validation;
using iText.Pdfua.Checkers;
+using iText.Pdfua.Exceptions;
using iText.Pdfua.Logs;
namespace iText.Pdfua {
@@ -50,11 +52,11 @@ public PdfUADocument(PdfWriter writer, PdfUAConfig config)
/// The properties for the PDF document.
/// The configuration for the PDF/UA document.
public PdfUADocument(PdfWriter writer, DocumentProperties properties, PdfUAConfig config)
- : base(ConfigureWriterProperties(writer), properties) {
+ : base(ConfigureWriterProperties(writer, config.GetConformance()), properties) {
this.pdfConformance = new PdfConformance(config.GetConformance());
SetupUAConfiguration(config);
ValidationContainer validationContainer = new ValidationContainer();
- PdfUA1Checker checker = new PdfUA1Checker(this);
+ PdfUAChecker checker = GetCorrectCheckerFromConformance(config.GetConformance());
validationContainer.AddChecker(checker);
this.GetDiContainer().Register(typeof(ValidationContainer), validationContainer);
this.pdfPageFactory = new PdfUAPageFactory(checker);
@@ -81,14 +83,14 @@ public PdfUADocument(PdfReader reader, PdfWriter writer, StampingProperties prop
}
SetupUAConfiguration(config);
ValidationContainer validationContainer = new ValidationContainer();
- PdfUA1Checker checker = new PdfUA1Checker(this);
+ PdfUAChecker checker = GetCorrectCheckerFromConformance(config.GetConformance());
validationContainer.AddChecker(checker);
this.GetDiContainer().Register(typeof(ValidationContainer), validationContainer);
this.pdfPageFactory = new PdfUAPageFactory(checker);
}
- private static PdfWriter ConfigureWriterProperties(PdfWriter writer) {
- writer.GetProperties().AddPdfUaXmpMetadata(PdfUAConformance.PDF_UA_1);
+ private static PdfWriter ConfigureWriterProperties(PdfWriter writer, PdfUAConformance uaConformance) {
+ writer.GetProperties().AddPdfUaXmpMetadata(uaConformance);
if (writer.GetPdfVersion() != null && !writer.GetPdfVersion().Equals(PdfVersion.PDF_1_7)) {
ITextLogManager.GetLogger(typeof(iText.Pdfua.PdfUADocument)).LogWarning(MessageFormatUtil.Format(PdfUALogMessageConstants
.WRITER_PROPERTIES_PDF_VERSION_WAS_OVERRIDDEN, PdfVersion.PDF_1_7));
@@ -98,12 +100,40 @@ private static PdfWriter ConfigureWriterProperties(PdfWriter writer) {
}
private void SetupUAConfiguration(PdfUAConfig config) {
- //basic configuration
+ // Basic configuration.
this.SetTagged();
this.GetCatalog().SetViewerPreferences(new PdfViewerPreferences().SetDisplayDocTitle(true));
this.GetCatalog().SetLang(new PdfString(config.GetLanguage()));
PdfDocumentInfo info = this.GetDocumentInfo();
info.SetTitle(config.GetTitle());
}
+
+ ///
+ /// Gets correct
+ ///
+ /// for specified PDF/UA conformance.
+ ///
+ /// the conformance for which checker is needed
+ /// the correct PDF/UA checker
+ private PdfUAChecker GetCorrectCheckerFromConformance(PdfUAConformance uaConformance) {
+ PdfUAChecker checker;
+ switch (uaConformance.GetPart()) {
+ case "1": {
+ checker = new PdfUA1Checker(this);
+ break;
+ }
+
+ case "2": {
+ checker = new PdfUA2Checker(this);
+ break;
+ }
+
+ default: {
+ throw new ArgumentException(PdfUAExceptionMessageConstants.CANNOT_FIND_PDF_UA_CHECKER_FOR_SPECIFIED_CONFORMANCE
+ );
+ }
+ }
+ return checker;
+ }
}
}
diff --git a/itext/itext.pdfua/itext/pdfua/PdfUAPage.cs b/itext/itext.pdfua/itext/pdfua/PdfUAPage.cs
index 307c1f1b7..9d50b91a7 100644
--- a/itext/itext.pdfua/itext/pdfua/PdfUAPage.cs
+++ b/itext/itext.pdfua/itext/pdfua/PdfUAPage.cs
@@ -20,6 +20,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
+using System;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Pdfua.Checkers;
@@ -27,18 +28,110 @@ You should have received a copy of the GNU Affero General Public License
namespace iText.Pdfua {
//\cond DO_NOT_DOCUMENT
internal class PdfUAPage : PdfPage {
- private readonly PdfUA1Checker checker;
+ private readonly PdfUAChecker checker;
+ ///
+ /// Creates new
+ ///
+ /// instance.
+ ///
+ ///
+ /// the
+ ///
+ /// object on which the
+ ///
+ /// will be based
+ ///
+ ///
+ ///
+ ///
+ /// to check the requirements of the PDF/UA-1 standard
+ ///
+ [System.ObsoleteAttribute(@"in favour of PdfUAPage(iText.Kernel.Pdf.PdfDictionary, iText.Pdfua.Checkers.PdfUAChecker)"
+ )]
protected internal PdfUAPage(PdfDictionary pdfObject, PdfUA1Checker checker)
: base(pdfObject) {
this.checker = checker;
}
+ ///
+ /// Creates new
+ ///
+ /// instance.
+ ///
+ ///
+ /// the
+ ///
+ /// object which will contain the
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// the size of the
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// to check the requirements of the PDF/UA-1 standard
+ ///
+ [System.ObsoleteAttribute(@"in favour of PdfUAPage(iText.Kernel.Pdf.PdfDocument, iText.Kernel.Geom.PageSize, iText.Pdfua.Checkers.PdfUAChecker)"
+ )]
protected internal PdfUAPage(PdfDocument pdfDocument, PageSize pageSize, PdfUA1Checker checker)
: base(pdfDocument, pageSize) {
this.checker = checker;
}
+ ///
+ /// Creates new
+ ///
+ /// instance.
+ ///
+ ///
+ /// the
+ ///
+ /// object on which the
+ ///
+ /// will be based
+ ///
+ ///
+ ///
+ ///
+ /// to check the requirements of the PDF/UA standard
+ ///
+ protected internal PdfUAPage(PdfDictionary pdfObject, PdfUAChecker checker)
+ : base(pdfObject) {
+ this.checker = checker;
+ }
+
+ ///
+ /// Creates new
+ ///
+ /// instance.
+ ///
+ ///
+ /// the
+ ///
+ /// object which will contain the
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// the size of the
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// to check the requirements of the PDF/UA standard
+ ///
+ protected internal PdfUAPage(PdfDocument pdfDocument, PageSize pageSize, PdfUAChecker checker)
+ : base(pdfDocument, pageSize) {
+ this.checker = checker;
+ }
+
public override void Flush(bool flushResourcesContentStreams) {
if (GetDocument().IsClosing()) {
base.Flush(flushResourcesContentStreams);
diff --git a/itext/itext.pdfua/itext/pdfua/PdfUAPageFactory.cs b/itext/itext.pdfua/itext/pdfua/PdfUAPageFactory.cs
index d04996652..59bc6e7ad 100644
--- a/itext/itext.pdfua/itext/pdfua/PdfUAPageFactory.cs
+++ b/itext/itext.pdfua/itext/pdfua/PdfUAPageFactory.cs
@@ -20,6 +20,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
+using System;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Pdfua.Checkers;
@@ -28,7 +29,7 @@ namespace iText.Pdfua {
//\cond DO_NOT_DOCUMENT
/// The class implements PDF page factory which is used for creating correct PDF/UA documents.
internal class PdfUAPageFactory : IPdfPageFactory {
- private readonly PdfUA1Checker checker;
+ private readonly PdfUAChecker checker;
///
/// Instantiates a new
@@ -37,10 +38,22 @@ internal class PdfUAPageFactory : IPdfPageFactory {
/// .
///
/// the PDF/UA checker
+ [System.ObsoleteAttribute(@"in favour of PdfUAPageFactory(iText.Pdfua.Checkers.PdfUAChecker)")]
public PdfUAPageFactory(PdfUA1Checker checker) {
this.checker = checker;
}
+ ///
+ /// Instantiates a new
+ ///
+ /// instance based on
+ /// .
+ ///
+ /// the PDF/UA checker
+ public PdfUAPageFactory(PdfUAChecker checker) {
+ this.checker = checker;
+ }
+
///
/// the
///
diff --git a/itext/itext.pdfua/itext/pdfua/checkers/PdfUA1Checker.cs b/itext/itext.pdfua/itext/pdfua/checkers/PdfUA1Checker.cs
index bfc11ad44..a44e5ab3d 100644
--- a/itext/itext.pdfua/itext/pdfua/checkers/PdfUA1Checker.cs
+++ b/itext/itext.pdfua/itext/pdfua/checkers/PdfUA1Checker.cs
@@ -22,8 +22,6 @@ 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.Datastructures;
using iText.Commons.Utils;
using iText.Kernel.Font;
@@ -39,16 +37,23 @@ You should have received a copy of the GNU Affero General Public License
using iText.Pdfua.Checkers.Utils.Headings;
using iText.Pdfua.Checkers.Utils.Tables;
using iText.Pdfua.Exceptions;
-using iText.Pdfua.Logs;
namespace iText.Pdfua.Checkers {
- /// The class defines the requirements of the PDF/UA-1 standard.
+ ///
+ /// The class defines the requirements of the PDF/UA-1 standard and contains
+ /// method implementations from the abstract
+ ///
+ /// class.
+ ///
///
- /// The class defines the requirements of the PDF/UA-1 standard.
+ /// The class defines the requirements of the PDF/UA-1 standard and contains
+ /// method implementations from the abstract
+ ///
+ /// class.
///
- /// The specification implemented by this class is ISO 14289-1
+ /// The specification implemented by this class is ISO 14289-1.
///
- public class PdfUA1Checker : IValidationChecker {
+ public class PdfUA1Checker : PdfUAChecker {
private readonly PdfDocument pdfDocument;
private readonly TagStructureContext tagStructureContext;
@@ -57,12 +62,11 @@ public class PdfUA1Checker : IValidationChecker {
private readonly PdfUAValidationContext context;
- private bool warnedOnPageFlush = false;
-
/// Creates PdfUA1Checker instance with PDF document which will be validated against PDF/UA-1 standard.
///
/// the document to validate
- public PdfUA1Checker(PdfDocument pdfDocument) {
+ public PdfUA1Checker(PdfDocument pdfDocument)
+ : base() {
this.pdfDocument = pdfDocument;
this.tagStructureContext = new TagStructureContext(pdfDocument);
this.context = new PdfUAValidationContext(pdfDocument);
@@ -72,7 +76,7 @@ public PdfUA1Checker(PdfDocument pdfDocument) {
///
/// .
///
- public virtual void Validate(IValidationContext context) {
+ public override void Validate(IValidationContext context) {
switch (context.GetType()) {
case ValidationType.PDF_DOCUMENT: {
PdfDocumentValidationContext pdfDocContext = (PdfDocumentValidationContext)context;
@@ -131,19 +135,10 @@ public virtual void Validate(IValidationContext context) {
///
/// .
///
- public virtual bool IsPdfObjectReadyToFlush(PdfObject @object) {
+ public override bool IsPdfObjectReadyToFlush(PdfObject @object) {
return true;
}
- /// Logs a warn on page flushing that page flushing is disabled in PDF/UA mode.
- public virtual void WarnOnPageFlush() {
- if (!warnedOnPageFlush) {
- ITextLogManager.GetLogger(typeof(iText.Pdfua.Checkers.PdfUA1Checker)).LogWarning(PdfUALogMessageConstants.
- PAGE_FLUSHING_DISABLED);
- warnedOnPageFlush = true;
- }
- }
-
/// Verify the conformity of the file specification dictionary.
///
/// the
diff --git a/itext/itext.pdfua/itext/pdfua/checkers/PdfUA2Checker.cs b/itext/itext.pdfua/itext/pdfua/checkers/PdfUA2Checker.cs
new file mode 100644
index 000000000..ffc599f48
--- /dev/null
+++ b/itext/itext.pdfua/itext/pdfua/checkers/PdfUA2Checker.cs
@@ -0,0 +1,73 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2025 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using iText.Kernel.Pdf;
+using iText.Kernel.Validation;
+using iText.Pdfua.Checkers.Utils;
+
+namespace iText.Pdfua.Checkers {
+ ///
+ /// The class defines the requirements of the PDF/UA-2 standard and contains
+ /// method implementations from the abstract
+ ///
+ /// class.
+ ///
+ ///
+ /// The class defines the requirements of the PDF/UA-2 standard and contains
+ /// method implementations from the abstract
+ ///
+ /// class.
+ ///
+ /// The specification implemented by this class is ISO 14289-2.
+ ///
+ public class PdfUA2Checker : PdfUAChecker {
+ private readonly PdfDocument pdfDocument;
+
+ private readonly PdfUAValidationContext context;
+
+ ///
+ /// Creates
+ ///
+ /// instance with PDF document which will be validated against PDF/UA-2 standard.
+ ///
+ /// the document to validate
+ public PdfUA2Checker(PdfDocument pdfDocument)
+ : base() {
+ this.pdfDocument = pdfDocument;
+ this.context = new PdfUAValidationContext(pdfDocument);
+ }
+
+ ///
+ /// .
+ ///
+ public override void Validate(IValidationContext context) {
+ }
+
+ // Empty for now.
+ ///
+ /// .
+ ///
+ public override bool IsPdfObjectReadyToFlush(PdfObject @object) {
+ return true;
+ }
+ }
+}
diff --git a/itext/itext.pdfua/itext/pdfua/checkers/PdfUAChecker.cs b/itext/itext.pdfua/itext/pdfua/checkers/PdfUAChecker.cs
new file mode 100644
index 000000000..c408f23f1
--- /dev/null
+++ b/itext/itext.pdfua/itext/pdfua/checkers/PdfUAChecker.cs
@@ -0,0 +1,68 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2025 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using Microsoft.Extensions.Logging;
+using iText.Commons;
+using iText.Kernel.Pdf;
+using iText.Kernel.Validation;
+using iText.Pdfua.Logs;
+
+namespace iText.Pdfua.Checkers {
+ /// An abstract class that will run through all necessary checks defined in the different PDF/UA standards.
+ ///
+ ///
+ /// An abstract class that will run through all necessary checks defined in the different PDF/UA standards. A number of
+ /// common checks are executed in this class, while standard-dependent specifications are implemented in the available
+ /// subclasses. The standard that is followed is the series of ISO 14289 specifications, currently generations 1 and 2.
+ ///
+ /// While it is possible to subclass this method and implement its abstract methods in client code, this is not
+ /// encouraged and will have little effect. It is not possible to plug custom implementations into iText, because
+ /// iText should always refuse to create non-compliant PDF/UA, which would be possible with client code implementations.
+ /// Any future generations of the PDF/UA standard and its derivatives will get their own implementation in the iText -
+ /// pdfua project.
+ ///
+ public abstract class PdfUAChecker : IValidationChecker {
+ private bool warnedOnPageFlush = false;
+
+ ///
+ /// Creates new
+ ///
+ /// instance.
+ ///
+ protected internal PdfUAChecker() {
+ }
+
+ // Empty constructor.
+ /// Logs a warn on page flushing that page flushing is disabled in PDF/UA mode.
+ public virtual void WarnOnPageFlush() {
+ if (!warnedOnPageFlush) {
+ ITextLogManager.GetLogger(typeof(iText.Pdfua.Checkers.PdfUAChecker)).LogWarning(PdfUALogMessageConstants.PAGE_FLUSHING_DISABLED
+ );
+ warnedOnPageFlush = true;
+ }
+ }
+
+ public abstract bool IsPdfObjectReadyToFlush(PdfObject arg1);
+
+ public abstract void Validate(IValidationContext arg1);
+ }
+}
diff --git a/itext/itext.pdfua/itext/pdfua/exceptions/PdfUAExceptionMessageConstants.cs b/itext/itext.pdfua/itext/pdfua/exceptions/PdfUAExceptionMessageConstants.cs
index ce342392f..cbae65146 100644
--- a/itext/itext.pdfua/itext/pdfua/exceptions/PdfUAExceptionMessageConstants.cs
+++ b/itext/itext.pdfua/itext/pdfua/exceptions/PdfUAExceptionMessageConstants.cs
@@ -25,64 +25,64 @@ You should have received a copy of the GNU Affero General Public License
namespace iText.Pdfua.Exceptions {
/// Class that bundles all the error message templates as constants.
public sealed class PdfUAExceptionMessageConstants {
- public const String ONE_OR_MORE_STANDARD_ROLE_REMAPPED = "One or more standard types are remapped.";
-
- public const String TAG_HASNT_BEEN_ADDED_BEFORE_CONTENT_ADDING = "Tag hasn't been added before adding content to the canvas.";
+ public const String ANNOTATION_OF_TYPE_0_SHOULD_HAVE_CONTENTS_OR_ALT_KEY = "Annotation of type {0} shall "
+ + "have contents or alternate description (in the form of an Alt entry in the enclosing structure element).";
- public const String CONTENT_IS_NOT_REAL_CONTENT_AND_NOT_ARTIFACT = "Content is neither marked as Artifact nor tagged as real content.";
+ public const String ANNOT_TRAP_NET_IS_NOT_PERMITTED = "Annotations of subtype TrapNet shall not be permitted.";
public const String ARTIFACT_CANT_BE_INSIDE_REAL_CONTENT = "Content marked as artifact may only reside in Artifact content.";
- public const String REAL_CONTENT_CANT_BE_INSIDE_ARTIFACT = "Content marked as content may not reside in Artifact content.";
+ public const String CANNOT_FIND_PDF_UA_CHECKER_FOR_SPECIFIED_CONFORMANCE = "Cannot find an appropriate " +
+ "PDF/UA checker for the specified conformance.";
- public const String CONTENT_WITH_MCID_BUT_MCID_NOT_FOUND_IN_STRUCT_TREE_ROOT = "Content with MCID, but MCID wasn't found in StructTreeRoot.";
+ public const String CELL_CANT_BE_DETERMINED_ALGORITHMICALLY = "TD cell row:{0} col:{1} in table {2} does"
+ + " not contain a valid Headers attribute, and Headers for this cell cannot be determined algorithmically.";
- public const String FONT_SHOULD_BE_EMBEDDED = "Following font(s) are not embedded: {0}";
+ public const String CELL_HAS_INVALID_ROLE = "Cell: row {0} ({1}) col {2} has invalid role.";
- public const String METADATA_SHALL_BE_PRESENT_IN_THE_CATALOG_DICTIONARY = "Metadata shall be present in the catalog dictionary";
+ public const String CONTENT_IS_NOT_REAL_CONTENT_AND_NOT_ARTIFACT = "Content is neither marked as Artifact nor tagged as real content.";
- public const String REAL_CONTENT_INSIDE_ARTIFACT_OR_VICE_VERSA = "Tagged content is present inside content marked as Artifact or vice versa.";
+ public const String CONTENT_WITH_MCID_BUT_MCID_NOT_FOUND_IN_STRUCT_TREE_ROOT = "Content with MCID, but MCID wasn't found in StructTreeRoot.";
- public const String SUSPECTS_ENTRY_IN_MARK_INFO_DICTIONARY_SHALL_NOT_HAVE_A_VALUE_OF_TRUE = "Suspects entry in mark info dictionary shall not have a value of true.";
+ public const String CT_OR_ALT_ENTRY_IS_MISSING_IN_MEDIA_CLIP = "CT or Alt entry is missing from the media "
+ + "clip data dictionary.";
- public const String TAG_MAPPING_DOESNT_TERMINATE_WITH_STANDARD_TYPE = "\"{0}\" tag mapping does not terminate with a standard type.";
+ public const String DOCUMENT_SHALL_CONTAIN_VALID_LANG_ENTRY = "Document does not contain valid lang entry.";
- public const String IMAGE_SHALL_HAVE_ALT = "Figure tags shall include an alternative representation or " +
- "replacement text. call com.itextpdf.kernel.pdf.tagutils.AccessibilityProperties#setActualText or com"
- + ".itextpdf.kernel.pdf.tagutils.AccessibilityProperties#setAlternateDescription to be PDF/UA compliant.";
+ public const String DOCUMENT_SHALL_CONTAIN_XMP_METADATA_STREAM = "Document shall contain a XMP metadata stream.";
- public const String CELL_HAS_INVALID_ROLE = "Cell: row {0} ({1}) col {2} has invalid role.";
+ public const String DOCUMENT_USES_BOTH_H_AND_HN = "Document uses both H and H# tags.";
- public const String TABLE_CONTAINS_EMPTY_CELLS = "Cell: row {0} ({1}) col {2} is empty, each row should "
- + "have the same amount of columns when taking into account spanning.";
+ public const String DYNAMIC_XFA_FORMS_SHALL_NOT_BE_USED = "Dynamic XFA forms shall not be used.";
- public const String CELL_CANT_BE_DETERMINED_ALGORITHMICALLY = "TD cell row:{0} col:{1} in table {2} does"
- + " not contain a valid Headers attribute, and Headers for this cell cannot be determined algorithmically.";
+ public const String FILE_SPECIFICATION_DICTIONARY_SHALL_CONTAIN_F_KEY_AND_UF_KEY = "File specification dictionary shall contain f key and uf key.";
+
+ public const String FONT_SHOULD_BE_EMBEDDED = "Following font(s) are not embedded: {0}";
public const String FORMULA_SHALL_HAVE_ALT = "Formula tags shall include an alternative representation or "
+ "replacement text.";
- public const String NOTE_TAG_SHALL_HAVE_ID_ENTRY = "Note tags shall include a unique ID entry.";
-
public const String GLYPH_IS_NOT_DEFINED_OR_WITHOUT_UNICODE = "The '{0}' glyph either isn't defined in embedded font or doesn't have unicode mapping.";
- public const String DOCUMENT_SHALL_CONTAIN_XMP_METADATA_STREAM = "Document shall contain a XMP metadata stream.";
+ public const String H1_IS_SKIPPED = "Heading level 1 is skipped in a descending sequence of header levels.";
- public const String METADATA_SHALL_CONTAIN_UA_VERSION_IDENTIFIER = "Metadata shall contain correct pdfuaid:part version identifier.";
+ public const String HN_IS_SKIPPED = "Heading level {0} is skipped in a descending sequence of header " + "levels.";
- public const String METADATA_SHALL_CONTAIN_DC_TITLE_ENTRY = "Metadata shall contain dc:title entry.";
+ public const String IMAGE_SHALL_HAVE_ALT = "Figure tags shall include an alternative representation or " +
+ "replacement text. call com.itextpdf.kernel.pdf.tagutils.AccessibilityProperties#setActualText or com"
+ + ".itextpdf.kernel.pdf.tagutils.AccessibilityProperties#setAlternateDescription to be PDF/UA compliant.";
public const String INVALID_PDF_VERSION = "Specified document pdf version isn't supported in pdf/ua.";
- public const String H1_IS_SKIPPED = "Heading level 1 is skipped in a descending sequence of header levels.";
+ public const String LINK_ANNOTATION_SHOULD_HAVE_CONTENTS_KEY = "Annotation of type Link " + "shall contain an alternate description via their Contents key.";
- public const String HN_IS_SKIPPED = "Heading level {0} is skipped in a descending sequence of header " + "levels.";
+ public const String LINK_ANNOT_IS_NOT_NESTED_WITHIN_LINK = "A link annotation is not nested within a tag.";
- public const String MORE_THAN_ONE_H_TAG = "A node contains more than one H tag.";
+ public const String METADATA_SHALL_BE_PRESENT_IN_THE_CATALOG_DICTIONARY = "Metadata shall be present in the catalog dictionary";
- public const String DOCUMENT_USES_BOTH_H_AND_HN = "Document uses both H and H# tags.";
+ public const String METADATA_SHALL_CONTAIN_DC_TITLE_ENTRY = "Metadata shall contain dc:title entry.";
- public const String DOCUMENT_SHALL_CONTAIN_VALID_LANG_ENTRY = "Document does not contain valid lang entry.";
+ public const String METADATA_SHALL_CONTAIN_UA_VERSION_IDENTIFIER = "Metadata shall contain correct pdfuaid:part version identifier.";
public const String MISSING_FORM_FIELD_DESCRIPTION = "Document form fields missing both TU entry and " + "alternative description. For PdfFormfields use PdfFormfield#setAlternativeName"
+ "(\"Your alternative description\"); For the layout engine use Element#getAccesibilityProperties()"
@@ -91,44 +91,46 @@ public sealed class PdfUAExceptionMessageConstants {
public const String MISSING_VIEWER_PREFERENCES = "ViewerPreferences dictionary of the Catalog dictionary "
+ "does not contain a DisplayDocTitle entry.";
- public const String VIEWER_PREFERENCES_IS_FALSE = "ViewerPreferences dictionary of the Catalog dictionary "
- + "contains a DisplayDocTitle entry with a value of false.";
+ public const String MORE_THAN_ONE_H_TAG = "A node contains more than one H tag.";
public const String NAME_ENTRY_IS_MISSING_OR_EMPTY_IN_OCG = "Name entry is missing or has " + "an empty string as its value in an Optional Content Configuration Dictionary.";
- public const String OCG_SHALL_NOT_CONTAIN_AS_ENTRY = "An AS entry appears in an Optional Content.";
+ public const String NON_UNIQUE_ID_ENTRY_IN_STRUCT_TREE_ROOT = "ID entry '{0}' shall be unique among all elements in the document’s structure hierarchy";
+
+ public const String NOTE_TAG_SHALL_HAVE_ID_ENTRY = "Note tags shall include a unique ID entry.";
public const String OCG_PROPERTIES_CONFIG_SHALL_BE_AN_ARRAY = "Optional Content properties " + "configs shall be an array.";
- public const String DYNAMIC_XFA_FORMS_SHALL_NOT_BE_USED = "Dynamic XFA forms shall not be used.";
+ public const String OCG_SHALL_NOT_CONTAIN_AS_ENTRY = "An AS entry appears in an Optional Content.";
- public const String FILE_SPECIFICATION_DICTIONARY_SHALL_CONTAIN_F_KEY_AND_UF_KEY = "File specification dictionary shall contain f key and uf key.";
+ public const String ONE_OR_MORE_STANDARD_ROLE_REMAPPED = "One or more standard types are remapped.";
- public const String NON_UNIQUE_ID_ENTRY_IN_STRUCT_TREE_ROOT = "ID entry '{0}' shall be unique among all elements "
- + "in the document’s structure hierarchy";
+ public const String PAGE_WITH_ANNOT_DOES_NOT_HAVE_TABS_WITH_S = "A page with annotation(s) doesn't " + "contain Tabs key with S value.";
- public const String LINK_ANNOT_IS_NOT_NESTED_WITHIN_LINK = "A link annotation is not nested within a tag.";
+ public const String PRINTER_MARK_IS_NOT_PERMITTED = "Annotations of subtype PrinterMark shall not be" + " included in logical structure.";
- public const String ANNOT_TRAP_NET_IS_NOT_PERMITTED = "Annotations of subtype TrapNet shall not be permitted.";
+ public const String P_VALUE_IS_ABSENT_IN_ENCRYPTION_DICTIONARY = "Permissions are absent " + "in pdf encryption dictionary.";
- public const String PAGE_WITH_ANNOT_DOES_NOT_HAVE_TABS_WITH_S = "A page with annotation(s) doesn't contains Tabs key with S value.";
+ public const String REAL_CONTENT_CANT_BE_INSIDE_ARTIFACT = "Content marked as content may not reside in Artifact content.";
- public const String P_VALUE_IS_ABSENT_IN_ENCRYPTION_DICTIONARY = "Permissions are absent " + "in pdf encryption dictionary.";
+ public const String REAL_CONTENT_INSIDE_ARTIFACT_OR_VICE_VERSA = "Tagged content is present inside content marked as Artifact or vice versa.";
- public const String TENTH_BIT_OF_P_VALUE_IN_ENCRYPTION_SHOULD_BE_NON_ZERO = "10th bit of P value of " + "Encryption dictionary should be 1 if the document is tagged.";
+ public const String SUSPECTS_ENTRY_IN_MARK_INFO_DICTIONARY_SHALL_NOT_HAVE_A_VALUE_OF_TRUE = "Suspects entry in mark info dictionary shall not have a value of true.";
- public const String ANNOTATION_OF_TYPE_0_SHOULD_HAVE_CONTENTS_OR_ALT_KEY = "Annotation of type {0} shall "
- + "have contents or alternate description (in the form of an Alt entry in the enclosing structure element).";
+ public const String TABLE_CONTAINS_EMPTY_CELLS = "Cell: row {0} ({1}) col {2} is empty, each row should "
+ + "have the same amount of columns when taking into account spanning.";
- public const String LINK_ANNOTATION_SHOULD_HAVE_CONTENTS_KEY = "Annotation of type Link " + "shall contain an alternate description via their Contents key.";
+ public const String TAG_HASNT_BEEN_ADDED_BEFORE_CONTENT_ADDING = "Tag hasn't been added before adding content to the canvas.";
- public const String CT_OR_ALT_ENTRY_IS_MISSING_IN_MEDIA_CLIP = "CT or Alt entry is missing from the media "
- + "clip data dictionary.";
+ public const String TAG_MAPPING_DOESNT_TERMINATE_WITH_STANDARD_TYPE = "\"{0}\" tag mapping does not terminate with a standard type.";
+
+ public const String TENTH_BIT_OF_P_VALUE_IN_ENCRYPTION_SHOULD_BE_NON_ZERO = "10th bit of P value of " + "Encryption dictionary should be 1 if the document is tagged.";
- public const String PRINTER_MARK_IS_NOT_PERMITTED = "Annotations of subtype PrinterMark shall not be included in logical structure.";
+ public const String VIEWER_PREFERENCES_IS_FALSE = "ViewerPreferences dictionary of the Catalog dictionary "
+ + "contains a DisplayDocTitle entry with a value of false.";
private PdfUAExceptionMessageConstants() {
}
- // Empty constructor
+ // Empty constructor.
}
}
diff --git a/port-hash b/port-hash
index ebdf73272..9d5129daf 100644
--- a/port-hash
+++ b/port-hash
@@ -1 +1 @@
-ff83ae4f7d0f91c1aef18b34b918be26e6751d97
+aa87065818a20aa22cb9dea98158c24e6661e529