Skip to content

Commit dc30581

Browse files
author
Eugene Bochilo
committed
Support Replacements and alternatives rules for UA-2
DEVSIX-9003 Autoported commit. Original commit hash: [7e6d68732] Manual files: pdfua/src/main/java/com/itextpdf/pdfua/checkers/utils/ua2/PdfUA2StringChecker.java
1 parent 9fdb347 commit dc30581

File tree

13 files changed

+764
-11
lines changed

13 files changed

+764
-11
lines changed

itext.tests/itext.pdfa.tests/itext/pdfa/PdfAFontTest.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ You should have received a copy of the GNU Affero General Public License
3434
using iText.Layout.Element;
3535
using iText.Pdfa.Exceptions;
3636
using iText.Test;
37+
using iText.Test.Attributes;
3738
using iText.Test.Pdfa;
3839

3940
namespace iText.Pdfa {
@@ -324,6 +325,8 @@ public virtual void GlyphLineWithUndefinedGlyphsTest() {
324325
}
325326

326327
[NUnit.Framework.Test]
328+
[LogMessage(iText.IO.Logs.IoLogMessageConstant.COULD_NOT_FIND_GLYPH_WITH_CODE, Count = 6)]
329+
[NUnit.Framework.Ignore("DEVSIX-9125")]
327330
public virtual void PdfArrayWithUndefinedGlyphsTest() {
328331
String outPdf = DESTINATION_FOLDER + "pdfArrayWithUndefinedGlyphs.pdf";
329332
PdfWriter writer = new PdfWriter(outPdf, new WriterProperties().SetPdfVersion(PdfVersion.PDF_2_0));
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2025 Apryse Group NV
4+
Authors: Apryse Software.
5+
6+
This program is offered under a commercial and under the AGPL license.
7+
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
8+
9+
AGPL licensing:
10+
This program is free software: you can redistribute it and/or modify
11+
it under the terms of the GNU Affero General Public License as published by
12+
the Free Software Foundation, either version 3 of the License, or
13+
(at your option) any later version.
14+
15+
This program is distributed in the hope that it will be useful,
16+
but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
GNU Affero General Public License for more details.
19+
20+
You should have received a copy of the GNU Affero General Public License
21+
along with this program. If not, see <https://www.gnu.org/licenses/>.
22+
*/
23+
using System;
24+
using System.Collections.Generic;
25+
using iText.Commons.Utils;
26+
using iText.IO.Font;
27+
using iText.IO.Font.Otf;
28+
using iText.Kernel.Font;
29+
using iText.Kernel.Pdf;
30+
using iText.Kernel.Pdf.Canvas;
31+
using iText.Kernel.Pdf.Tagging;
32+
using iText.Kernel.Pdf.Tagutils;
33+
using iText.Layout.Element;
34+
using iText.Pdfua;
35+
using iText.Pdfua.Exceptions;
36+
using iText.Test;
37+
38+
namespace iText.Pdfua.Checkers {
39+
[NUnit.Framework.Category("IntegrationTest")]
40+
public class PdfUACanvasTextTest : ExtendedITextTest {
41+
private static readonly String DESTINATION_FOLDER = TestUtil.GetOutputPath() + "/pdfua/PdfUACanvasTextTest/";
42+
43+
private static readonly String FONT = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
44+
.CurrentContext.TestDirectory) + "/resources/itext/pdfua/font/iTextFreeSansWithE001Glyph.ttf";
45+
46+
private UaValidationTestFramework framework;
47+
48+
[NUnit.Framework.OneTimeSetUp]
49+
public static void Before() {
50+
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
51+
}
52+
53+
[NUnit.Framework.SetUp]
54+
public virtual void SetUp() {
55+
framework = new UaValidationTestFramework(DESTINATION_FOLDER, false);
56+
}
57+
58+
public static IList<String> TextRepresentation() {
59+
return JavaUtil.ArraysAsList("text", "array", "glyphs");
60+
}
61+
62+
[NUnit.Framework.Test]
63+
public virtual void PuaValueInLayoutTest() {
64+
String filename = "puaValueInLayoutTest";
65+
framework.AddSuppliers(new _Generator_81());
66+
framework.AssertBothFail(filename, PdfUAExceptionMessageConstants.PUA_CONTENT_WITHOUT_ALT, PdfUAConformance
67+
.PDF_UA_2);
68+
}
69+
70+
private sealed class _Generator_81 : UaValidationTestFramework.Generator<IBlockElement> {
71+
public _Generator_81() {
72+
}
73+
74+
public IBlockElement Generate() {
75+
Paragraph paragraph = new Paragraph("hello_" + "\uE001");
76+
paragraph.SetFont(PdfUACanvasTextTest.LoadFont());
77+
return paragraph;
78+
}
79+
}
80+
81+
[NUnit.Framework.TestCaseSource("TextRepresentation")]
82+
public virtual void PuaValueWithoutAttributesTest(String textRepresentation) {
83+
String filename = "puaValueWithoutAttributesTest_" + textRepresentation;
84+
framework.AddBeforeGenerationHook((document) => {
85+
PdfCanvas canvas = new PdfCanvas(document.AddNewPage());
86+
TagTreePointer pointer = document.GetTagStructureContext().GetAutoTaggingPointer();
87+
pointer.AddTag(StandardRoles.P);
88+
pointer.SetPageForTagging(document.GetFirstPage());
89+
canvas.BeginText();
90+
PdfFont font = LoadFont();
91+
canvas.SetFontAndSize(font, 24);
92+
canvas.OpenTag(pointer.GetTagReference());
93+
AddPuaTextToCanvas(canvas, textRepresentation, font);
94+
canvas.CloseTag();
95+
canvas.EndText();
96+
}
97+
);
98+
framework.AssertBothFail(filename, PdfUAExceptionMessageConstants.PUA_CONTENT_WITHOUT_ALT, PdfUAConformance
99+
.PDF_UA_2);
100+
}
101+
102+
[NUnit.Framework.TestCaseSource("TextRepresentation")]
103+
public virtual void PuaValueWithAltOnTagTest(String textRepresentation) {
104+
String filename = "puaValueWithAltOnTagTest_" + textRepresentation;
105+
framework.AddBeforeGenerationHook((document) => {
106+
PdfCanvas canvas = new PdfCanvas(document.AddNewPage());
107+
TagTreePointer pointer = document.GetTagStructureContext().GetAutoTaggingPointer();
108+
pointer.AddTag(StandardRoles.P);
109+
pointer.SetPageForTagging(document.GetFirstPage());
110+
pointer.ApplyProperties(new DefaultAccessibilityProperties(StandardRoles.P).SetAlternateDescription("alt description"
111+
));
112+
canvas.BeginText();
113+
PdfFont font = LoadFont();
114+
canvas.SetFontAndSize(font, 24);
115+
CanvasTag canvasTag = new CanvasTag(pointer.GetTagReference().GetRole(), pointer.GetTagReference().CreateNextMcid
116+
());
117+
canvas.OpenTag(canvasTag);
118+
AddPuaTextToCanvas(canvas, textRepresentation, font);
119+
canvas.CloseTag();
120+
canvas.EndText();
121+
}
122+
);
123+
framework.AssertBothValid(filename, PdfUAConformance.PDF_UA_2);
124+
}
125+
126+
[NUnit.Framework.TestCaseSource("TextRepresentation")]
127+
public virtual void PuaValueWithActualTextOnTagTest(String textRepresentation) {
128+
String filename = "puaValueWithActualTextOnTagTest_" + textRepresentation;
129+
framework.AddBeforeGenerationHook((document) => {
130+
PdfCanvas canvas = new PdfCanvas(document.AddNewPage());
131+
TagTreePointer pointer = document.GetTagStructureContext().GetAutoTaggingPointer();
132+
pointer.AddTag(StandardRoles.P);
133+
pointer.SetPageForTagging(document.GetFirstPage());
134+
pointer.ApplyProperties(new DefaultAccessibilityProperties(StandardRoles.P).SetActualText("alt description"
135+
));
136+
canvas.BeginText();
137+
PdfFont font = LoadFont();
138+
canvas.SetFontAndSize(font, 24);
139+
CanvasTag canvasTag = new CanvasTag(pointer.GetTagReference().GetRole(), pointer.GetTagReference().CreateNextMcid
140+
());
141+
canvas.OpenTag(canvasTag);
142+
AddPuaTextToCanvas(canvas, textRepresentation, font);
143+
canvas.CloseTag();
144+
canvas.EndText();
145+
}
146+
);
147+
framework.AssertBothValid(filename, PdfUAConformance.PDF_UA_2);
148+
}
149+
150+
[NUnit.Framework.TestCaseSource("TextRepresentation")]
151+
public virtual void PuaValueWithAltOnCanvasTest(String textRepresentation) {
152+
String filename = "puaValueWithAltOnCanvasTest_" + textRepresentation;
153+
framework.AddBeforeGenerationHook((document) => {
154+
PdfCanvas canvas = new PdfCanvas(document.AddNewPage());
155+
TagTreePointer pointer = document.GetTagStructureContext().GetAutoTaggingPointer();
156+
pointer.AddTag(StandardRoles.P);
157+
pointer.SetPageForTagging(document.GetFirstPage());
158+
canvas.BeginText();
159+
PdfFont font = LoadFont();
160+
canvas.SetFontAndSize(font, 24);
161+
CanvasTag canvasTag = new CanvasTag(pointer.GetTagReference().GetRole(), pointer.GetTagReference().CreateNextMcid
162+
());
163+
canvasTag.AddProperty(PdfName.Alt, new PdfString("alt description"));
164+
canvas.OpenTag(canvasTag);
165+
AddPuaTextToCanvas(canvas, textRepresentation, font);
166+
canvas.CloseTag();
167+
canvas.EndText();
168+
}
169+
);
170+
framework.AssertBothValid(filename, PdfUAConformance.PDF_UA_2);
171+
}
172+
173+
[NUnit.Framework.TestCaseSource("TextRepresentation")]
174+
public virtual void PuaValueWithActualTextOnCanvasTest(String textRepresentation) {
175+
String filename = "puaValueWithActualTextOnCanvasTest_" + textRepresentation;
176+
framework.AddBeforeGenerationHook((document) => {
177+
PdfCanvas canvas = new PdfCanvas(document.AddNewPage());
178+
TagTreePointer pointer = document.GetTagStructureContext().GetAutoTaggingPointer();
179+
pointer.AddTag(StandardRoles.P);
180+
pointer.SetPageForTagging(document.GetFirstPage());
181+
canvas.BeginText();
182+
PdfFont font = LoadFont();
183+
canvas.SetFontAndSize(font, 24);
184+
CanvasTag canvasTag = new CanvasTag(pointer.GetTagReference().GetRole(), pointer.GetTagReference().CreateNextMcid
185+
());
186+
canvasTag.AddProperty(PdfName.ActualText, new PdfString("alt description"));
187+
canvas.OpenTag(canvasTag);
188+
AddPuaTextToCanvas(canvas, textRepresentation, font);
189+
canvas.CloseTag();
190+
canvas.EndText();
191+
}
192+
);
193+
framework.AssertBothValid(filename, PdfUAConformance.PDF_UA_2);
194+
}
195+
196+
[NUnit.Framework.TestCaseSource("TextRepresentation")]
197+
public virtual void PuaValueOnTwoPagesTest(String textRepresentation) {
198+
String filename = "puaValueOnTwoPagesTest_" + textRepresentation;
199+
framework.AddBeforeGenerationHook((document) => {
200+
// Text on page 1 contains PUA and alt, which is valid.
201+
PdfCanvas canvasOnPageOne = new PdfCanvas(document.AddNewPage());
202+
TagTreePointer pointer1 = document.GetTagStructureContext().GetAutoTaggingPointer();
203+
pointer1.AddTag(StandardRoles.P);
204+
pointer1.SetPageForTagging(document.GetFirstPage());
205+
pointer1.ApplyProperties(new DefaultAccessibilityProperties(StandardRoles.P).SetAlternateDescription("alt description"
206+
));
207+
canvasOnPageOne.BeginText();
208+
PdfFont font = LoadFont();
209+
canvasOnPageOne.SetFontAndSize(font, 24);
210+
CanvasTag canvasTag = new CanvasTag(pointer1.GetTagReference().GetRole(), pointer1.GetTagReference().CreateNextMcid
211+
());
212+
canvasOnPageOne.OpenTag(canvasTag);
213+
AddPuaTextToCanvas(canvasOnPageOne, textRepresentation, font);
214+
canvasOnPageOne.CloseTag();
215+
canvasOnPageOne.EndText();
216+
pointer1.MoveToParent();
217+
// Text on page two contains PUA, but doesn't contain alt, which is invalid.
218+
PdfCanvas canvasOnPageTwo = new PdfCanvas(document.AddNewPage());
219+
TagTreePointer pointer2 = document.GetTagStructureContext().GetAutoTaggingPointer();
220+
pointer2.AddTag(StandardRoles.P);
221+
pointer2.SetPageForTagging(document.GetPage(2));
222+
canvasOnPageTwo.BeginText();
223+
canvasOnPageTwo.SetFontAndSize(font, 24);
224+
canvasOnPageTwo.OpenTag(pointer2.GetTagReference());
225+
AddPuaTextToCanvas(canvasOnPageTwo, textRepresentation, font);
226+
canvasOnPageTwo.CloseTag();
227+
canvasOnPageTwo.EndText();
228+
}
229+
);
230+
framework.AssertBothFail(filename, PdfUAExceptionMessageConstants.PUA_CONTENT_WITHOUT_ALT, PdfUAConformance
231+
.PDF_UA_2);
232+
}
233+
234+
private void AddPuaTextToCanvas(PdfCanvas canvas, String textRepresentation, PdfFont font) {
235+
String stringWithPua = "hello_" + "\uE001";
236+
switch (textRepresentation) {
237+
case "text": {
238+
canvas.ShowText(stringWithPua);
239+
break;
240+
}
241+
242+
case "array": {
243+
PdfArray array = new PdfArray();
244+
array.Add(new PdfString(font.ConvertToBytes(stringWithPua)));
245+
canvas.ShowText(array);
246+
break;
247+
}
248+
249+
case "glyphs": {
250+
GlyphLine glyphLine = font.CreateGlyphLine(stringWithPua);
251+
canvas.ShowText(glyphLine);
252+
break;
253+
}
254+
}
255+
}
256+
257+
private static PdfFont LoadFont() {
258+
try {
259+
return PdfFontFactory.CreateFont(FONT, PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED
260+
);
261+
}
262+
catch (System.IO.IOException e) {
263+
throw new Exception(e.Message);
264+
}
265+
}
266+
}
267+
}

0 commit comments

Comments
 (0)