Skip to content

Commit e84bb3e

Browse files
committed
Move all logic from PdfA/UaDocuments to pluggalbe mechanisms into PdfDocument
DEVSIX-8623
1 parent dc8d3fe commit e84bb3e

File tree

53 files changed

+912
-1006
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+912
-1006
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2024 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+
package com.itextpdf.kernel.pdf;
24+
25+
import com.itextpdf.io.logs.IoLogMessageConstant;
26+
import com.itextpdf.kernel.font.PdfFont;
27+
import com.itextpdf.kernel.font.PdfFontFactory;
28+
29+
import java.io.IOException;
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
32+
33+
/**
34+
* The class defines a default font strategy for {@link PdfDocument}
35+
* which is used in the scope of {@link PdfDocument#getDefaultFont()}.
36+
*/
37+
public class DefaultFontStrategy {
38+
private final PdfDocument pdfDocument;
39+
private PdfFont defaultFont = null;
40+
41+
/**
42+
* Instantiates a new instance of {@link DefaultFontStrategy} which
43+
* will be used for passed {@link PdfDocument} instance.
44+
*
45+
* @param pdfDocument the pdf document for which the strategy will be used to
46+
*/
47+
public DefaultFontStrategy(PdfDocument pdfDocument) {
48+
this.pdfDocument = pdfDocument;
49+
}
50+
51+
/**
52+
* Gets default font.
53+
*
54+
* @return the {@link PdfFont} instance
55+
*/
56+
public PdfFont getFont() {
57+
if (defaultFont == null) {
58+
try {
59+
defaultFont = PdfFontFactory.createFont();
60+
if (pdfDocument.getWriter() != null) {
61+
defaultFont.makeIndirect(pdfDocument);
62+
}
63+
} catch (IOException e) {
64+
Logger logger = LoggerFactory.getLogger(DefaultFontStrategy.class);
65+
logger.error(IoLogMessageConstant.EXCEPTION_WHILE_CREATING_DEFAULT_FONT, e);
66+
defaultFont = null;
67+
}
68+
}
69+
return defaultFont;
70+
}
71+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2024 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+
package com.itextpdf.kernel.pdf;
24+
25+
/**
26+
* The class is helper which used inside {@link PdfDocument} to properly configure PDF document's info dictionary.
27+
*/
28+
public class DocumentInfoHelper {
29+
/**
30+
* If document info dictionary should be added to the trailer.
31+
*
32+
* @return {@code true} if should be added, otherwise {@code false}
33+
*/
34+
public boolean shouldAddDocumentInfoToTrailer() {
35+
return true;
36+
}
37+
38+
/**
39+
* Adjusts document info before it's flushing and adding to the trailer
40+
* if required, see {@link #shouldAddDocumentInfoToTrailer()}.
41+
*
42+
* @param documentInfo the {@link PdfDocumentInfo} instance to adjust
43+
*/
44+
public void adjustDocumentInfo(PdfDocumentInfo documentInfo) {
45+
// do nothing
46+
}
47+
}

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfConformance.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ This file is part of the iText (R) project.
2525
import com.itextpdf.kernel.xmp.XMPConst;
2626
import com.itextpdf.kernel.xmp.XMPException;
2727
import com.itextpdf.kernel.xmp.XMPMeta;
28+
import com.itextpdf.kernel.xmp.XMPMetaFactory;
29+
import com.itextpdf.kernel.xmp.XMPUtils;
30+
import com.itextpdf.kernel.xmp.options.PropertyOptions;
2831
import com.itextpdf.kernel.xmp.properties.XMPProperty;
2932

3033
/**
@@ -192,6 +195,46 @@ public static PdfConformance getConformance(XMPMeta meta) {
192195
return new PdfConformance(aLevel, uaLevel);
193196
}
194197

198+
/**
199+
* Sets required fields into XMP metadata according to passed PDF conformance.
200+
*
201+
* @param xmpMeta the xmp metadata to which required PDF conformance fields will be set
202+
* @param conformance the PDF conformance according to which XMP will be updated
203+
*
204+
* @throws XMPException if the file is not well-formed XML or if the parsing fails
205+
*/
206+
public static void setConformanceToXmp(XMPMeta xmpMeta, PdfConformance conformance) throws XMPException {
207+
if (conformance == null) {
208+
return;
209+
}
210+
// Don't set any property if property value was set, so if
211+
// smth was invalid in source document, it will be left as is.
212+
// But if e.g. for PDF/A-4 revision wasn't specified, we will fix it.
213+
if (conformance.isPdfUA()) {
214+
if (xmpMeta.getProperty(XMPConst.NS_PDFUA_ID, XMPConst.PART) == null) {
215+
xmpMeta.setPropertyInteger(XMPConst.NS_PDFUA_ID, XMPConst.PART, 1,
216+
new PropertyOptions(PropertyOptions.SEPARATE_NODE));
217+
}
218+
}
219+
if (conformance.isPdfA()) {
220+
final PdfAConformance aLevel = conformance.getAConformance();
221+
if (xmpMeta.getProperty(XMPConst.NS_PDFA_ID, XMPConst.PART) == null) {
222+
xmpMeta.setProperty(XMPConst.NS_PDFA_ID, XMPConst.PART, aLevel.getPart());
223+
}
224+
if (aLevel.getLevel() != null && xmpMeta.getProperty(XMPConst.NS_PDFA_ID, XMPConst.CONFORMANCE) == null) {
225+
xmpMeta.setProperty(XMPConst.NS_PDFA_ID, XMPConst.CONFORMANCE, aLevel.getLevel());
226+
}
227+
if ("4".equals(aLevel.getPart()) && xmpMeta.getProperty(XMPConst.NS_PDFA_ID, XMPConst.REV) == null) {
228+
xmpMeta.setProperty(XMPConst.NS_PDFA_ID, XMPConst.REV, PdfConformance.PDF_A_4_REVISION);
229+
}
230+
231+
if (xmpMeta.getPropertyInteger(XMPConst.NS_PDFUA_ID, XMPConst.PART) != null) {
232+
XMPMeta taggedExtensionMeta = XMPMetaFactory.parseFromString(PDF_UA_EXTENSION);
233+
XMPUtils.appendProperties(taggedExtensionMeta, xmpMeta, true, false);
234+
}
235+
}
236+
}
237+
195238
/**
196239
* Gets an instance of {@link PdfAConformance} based on passed part and level.
197240
*
@@ -257,4 +300,44 @@ private static PdfUAConformance getUAConformance(String part) {
257300
}
258301
return null;
259302
}
303+
304+
private static final String PDF_UA_EXTENSION =
305+
" <x:xmpmeta xmlns:x=\"adobe:ns:meta/\">\n" +
306+
" <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n" +
307+
" <rdf:Description rdf:about=\"\" xmlns:pdfaExtension=\"http://www.aiim.org/pdfa/ns/extension/\" xmlns:pdfaSchema=\"http://www.aiim.org/pdfa/ns/schema#\" xmlns:pdfaProperty=\"http://www.aiim.org/pdfa/ns/property#\">\n" +
308+
" <pdfaExtension:schemas>\n" +
309+
" <rdf:Bag>\n" +
310+
" <rdf:li rdf:parseType=\"Resource\">\n" +
311+
" <pdfaSchema:namespaceURI rdf:resource=\"http://www.aiim.org/pdfua/ns/id/\"/>\n" +
312+
" <pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix>\n" +
313+
" <pdfaSchema:schema>PDF/UA identification schema</pdfaSchema:schema>\n" +
314+
" <pdfaSchema:property>\n" +
315+
" <rdf:Seq>\n" +
316+
" <rdf:li rdf:parseType=\"Resource\">\n" +
317+
" <pdfaProperty:category>internal</pdfaProperty:category>\n" +
318+
" <pdfaProperty:description>PDF/UA version identifier</pdfaProperty:description>\n" +
319+
" <pdfaProperty:name>part</pdfaProperty:name>\n" +
320+
" <pdfaProperty:valueType>Integer</pdfaProperty:valueType>\n" +
321+
" </rdf:li>\n" +
322+
" <rdf:li rdf:parseType=\"Resource\">\n" +
323+
" <pdfaProperty:category>internal</pdfaProperty:category>\n" +
324+
" <pdfaProperty:description>PDF/UA amendment identifier</pdfaProperty:description>\n" +
325+
" <pdfaProperty:name>amd</pdfaProperty:name>\n" +
326+
" <pdfaProperty:valueType>Text</pdfaProperty:valueType>\n" +
327+
" </rdf:li>\n" +
328+
" <rdf:li rdf:parseType=\"Resource\">\n" +
329+
" <pdfaProperty:category>internal</pdfaProperty:category>\n" +
330+
" <pdfaProperty:description>PDF/UA corrigenda identifier</pdfaProperty:description>\n" +
331+
" <pdfaProperty:name>corr</pdfaProperty:name>\n" +
332+
" <pdfaProperty:valueType>Text</pdfaProperty:valueType>\n" +
333+
" </rdf:li>\n" +
334+
" </rdf:Seq>\n" +
335+
" </pdfaSchema:property>\n" +
336+
" </rdf:li>\n" +
337+
" </rdf:Bag>\n" +
338+
" </pdfaExtension:schemas>\n" +
339+
" </rdf:Description>\n" +
340+
" </rdf:RDF>\n" +
341+
" </x:xmpmeta>";
342+
260343
}

0 commit comments

Comments
 (0)