diff --git a/README.md b/README.md
index bec8eef932..f5f7a71f56 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ iText is licensed as [AGPL][agpl] software.
AGPL is a free / open source software license.
-This doesn't mean the software is gratis!
+This doesn't mean the software is [gratis][gratis]!
Buying a license is mandatory as soon as you develop commercial activities
distributing the iText software inside your product or deploying it on a network
@@ -41,3 +41,4 @@ Contact sales for more info: http://itextpdf.com/sales
[contributing]: CONTRIBUTING.md
[extrajars]: EXTRAJARS.md
[itext]: http://itextpdf.com/
+[gratis]: https://en.wikipedia.org/wiki/Gratis_versus_libre
diff --git a/itext/barcodeDataMatrix.pdf b/itext/barcodeDataMatrix.pdf
new file mode 100644
index 0000000000..4fadc31abc
Binary files /dev/null and b/itext/barcodeDataMatrix.pdf differ
diff --git a/itext/pom.xml b/itext/pom.xml
index ecf6aee9b5..f3b6c82bc2 100644
--- a/itext/pom.xml
+++ b/itext/pom.xml
@@ -10,7 +10,7 @@
itextpdf
- 5.5.11
+ 5.5.12iText CoreA Free Java-PDF library
@@ -268,18 +268,6 @@
http://developers.itextpdf.com/reference/classes
-
diff --git a/itext/src/main/java/com/itextpdf/awt/PdfGraphics2D.java b/itext/src/main/java/com/itextpdf/awt/PdfGraphics2D.java
index 42540f217c..321a499206 100644
--- a/itext/src/main/java/com/itextpdf/awt/PdfGraphics2D.java
+++ b/itext/src/main/java/com/itextpdf/awt/PdfGraphics2D.java
@@ -202,14 +202,15 @@ private static final class Kid {
private Graphics2D getDG2() {
if (dg2 == null) {
dg2 = new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB).createGraphics();
- dg2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
- setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
- setRenderingHint(HyperLinkKey.KEY_INSTANCE, HyperLinkKey.VALUE_HYPERLINKKEY_OFF);
+ dg2.setRenderingHints(rhints);
}
return dg2;
}
- private PdfGraphics2D() {}
+ private PdfGraphics2D() {
+ setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ setRenderingHint(HyperLinkKey.KEY_INSTANCE, HyperLinkKey.VALUE_HYPERLINKKEY_OFF);
+ }
public PdfGraphics2D(PdfContentByte cb, final float width, final float height) {
this(cb, width, height, null, false, false, 0);
@@ -507,21 +508,32 @@ public void drawString(String s, float x, float y) {
double width = 0;
if (font.getSize2D() > 0) {
- float scale = 1000 / font.getSize2D();
- Font derivedFont = font.deriveFont(AffineTransform.getScaleInstance(scale, scale));
- width = derivedFont.getStringBounds(s, getFontRenderContext()).getWidth();
- if (derivedFont.isTransformed())
- width /= scale;
+ if (RenderingHints.VALUE_FRACTIONALMETRICS_OFF.equals(getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS))) {
+ width = font.getStringBounds(s, getFontRenderContext()).getWidth();
+ } else {
+ float scale = 1000 / font.getSize2D();
+ Font derivedFont = font.deriveFont(AffineTransform.getScaleInstance(scale, scale));
+ width = derivedFont.getStringBounds(s, getFontRenderContext()).getWidth();
+ if (derivedFont.isTransformed())
+ width /= scale;
+ }
}
// if the hyperlink flag is set add an action to the text
Object url = getRenderingHint(HyperLinkKey.KEY_INSTANCE);
if (url != null && !url.equals(HyperLinkKey.VALUE_HYPERLINKKEY_OFF))
{
- float scale = 1000 / font.getSize2D();
- Font derivedFont = font.deriveFont(AffineTransform.getScaleInstance(scale, scale));
- double height = derivedFont.getStringBounds(s, getFontRenderContext()).getHeight();
- if (derivedFont.isTransformed())
- height /= scale;
+ double height = 0;
+ if (font.getSize2D() > 0) {
+ if (RenderingHints.VALUE_FRACTIONALMETRICS_OFF.equals(getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS))) {
+ height = font.getStringBounds(s, getFontRenderContext()).getHeight();
+ } else {
+ float scale = 1000 / font.getSize2D();
+ Font derivedFont = font.deriveFont(AffineTransform.getScaleInstance(scale, scale));
+ height = derivedFont.getStringBounds(s, getFontRenderContext()).getHeight();
+ if (derivedFont.isTransformed())
+ height /= scale;
+ }
+ }
double leftX = cb.getXTLM();
double leftY = cb.getYTLM();
PdfAction action = new PdfAction(url.toString());
@@ -817,32 +829,33 @@ public void setStroke(Stroke s) {
/**
* Sets a rendering hint
- * @param arg0
- * @param arg1
+ * @param hintKey
+ * @param hintValue
*/
@Override
- public void setRenderingHint(Key arg0, Object arg1) {
- if (arg1 != null) {
- rhints.put(arg0, arg1);
+ public void setRenderingHint(Key hintKey, Object hintValue) {
+ if (hintValue != null) {
+ rhints.put(hintKey, hintValue);
} else {
- if (arg0 instanceof HyperLinkKey)
- {
- rhints.put(arg0, HyperLinkKey.VALUE_HYPERLINKKEY_OFF);
+ if (hintKey instanceof HyperLinkKey) {
+ rhints.put(hintKey, HyperLinkKey.VALUE_HYPERLINKKEY_OFF);
}
- else
- {
- rhints.remove(arg0);
+ else {
+ rhints.remove(hintKey);
}
}
+ if (dg2 != null) {
+ dg2.setRenderingHint(hintKey, hintValue);
+ }
}
/**
- * @param arg0 a key
+ * @param hintKey a key
* @return the rendering hint
*/
@Override
- public Object getRenderingHint(Key arg0) {
- return rhints.get(arg0);
+ public Object getRenderingHint(Key hintKey) {
+ return rhints.get(hintKey);
}
/**
@@ -852,6 +865,9 @@ public Object getRenderingHint(Key arg0) {
public void setRenderingHints(Map,?> hints) {
rhints.clear();
rhints.putAll(hints);
+ if (dg2 != null) {
+ dg2.setRenderingHints(hints);
+ }
}
/**
@@ -860,6 +876,9 @@ public void setRenderingHints(Map,?> hints) {
@Override
public void addRenderingHints(Map,?> hints) {
rhints.putAll(hints);
+ if (dg2 != null) {
+ dg2.addRenderingHints(hints);
+ }
}
/**
diff --git a/itext/src/main/java/com/itextpdf/testutils/CompareTool.java b/itext/src/main/java/com/itextpdf/testutils/CompareTool.java
index 4d982ccd5c..ca688a8161 100644
--- a/itext/src/main/java/com/itextpdf/testutils/CompareTool.java
+++ b/itext/src/main/java/com/itextpdf/testutils/CompareTool.java
@@ -79,6 +79,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
+import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@@ -91,6 +92,7 @@
import java.util.StringTokenizer;
import java.util.TreeSet;
+import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -104,6 +106,8 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
@@ -375,6 +379,9 @@ public void writeReportToXml(OutputStream stream) throws ParserConfigurationExce
xmlReport.appendChild(root);
TransformerFactory tFactory = TransformerFactory.newInstance();
+ try {
+ tFactory.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ } catch (Exception exc) {}
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(xmlReport);
@@ -1193,6 +1200,7 @@ public boolean compareXmls(byte[] xml1, byte[] xml2) throws ParserConfigurationE
dbf.setIgnoringElementContentWhitespace(true);
dbf.setIgnoringComments(true);
DocumentBuilder db = dbf.newDocumentBuilder();
+ db.setEntityResolver(new SafeEmptyEntityResolver());
org.w3c.dom.Document doc1 = db.parse(new ByteArrayInputStream(xml1));
doc1.normalizeDocument();
@@ -1343,6 +1351,7 @@ public boolean compareXmls(String xml1, String xml2) throws ParserConfigurationE
dbf.setIgnoringElementContentWhitespace(true);
dbf.setIgnoringComments(true);
DocumentBuilder db = dbf.newDocumentBuilder();
+ db.setEntityResolver(new SafeEmptyEntityResolver());
org.w3c.dom.Document doc1 = db.parse(new File(xml1));
doc1.normalizeDocument();
@@ -1486,5 +1495,11 @@ public void renderImage(ImageRenderInfo renderInfo) {
}
+ private static class SafeEmptyEntityResolver implements EntityResolver {
+ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
+ return new InputSource(new StringReader(""));
+ }
+ }
+
}
diff --git a/itext/src/main/java/com/itextpdf/text/Version.java b/itext/src/main/java/com/itextpdf/text/Version.java
index ae5a984c7c..5d14310115 100644
--- a/itext/src/main/java/com/itextpdf/text/Version.java
+++ b/itext/src/main/java/com/itextpdf/text/Version.java
@@ -70,7 +70,7 @@ public final class Version {
* This String contains the version number of this iText release.
* For debugging purposes, we request you NOT to change this constant.
*/
- private String release = "5.5.11";
+ private String release = "5.5.12";
/**
* This String contains the iText version as shown in the producer line.
* iText is a product developed by iText Group NV.
diff --git a/itext/src/main/java/com/itextpdf/text/pdf/BarcodeDatamatrix.java b/itext/src/main/java/com/itextpdf/text/pdf/BarcodeDatamatrix.java
index 3b7155b380..fc1be9ed04 100644
--- a/itext/src/main/java/com/itextpdf/text/pdf/BarcodeDatamatrix.java
+++ b/itext/src/main/java/com/itextpdf/text/pdf/BarcodeDatamatrix.java
@@ -94,8 +94,15 @@ public class BarcodeDatamatrix {
*/
public static final int DM_B256 = 4;
/**
- * X21 encodation.
+ * X12 encodation.
*/
+ public static final int DM_X12 = 5;
+ /**
+ * X12 encodation.
+ *
+ * @deprecated Use {@link BarcodeDataMatrix#DM_X12} instead.
+ */
+ @Deprecated
public static final int DM_X21 = 5;
/**
* EDIFACT encodation.
@@ -115,39 +122,59 @@ public class BarcodeDatamatrix {
*/
public static final int DM_TEST = 64;
- private final static DmParams[] dmSizes = {
- new DmParams(10, 10, 10, 10, 3, 3, 5),
- new DmParams(12, 12, 12, 12, 5, 5, 7),
- new DmParams(8, 18, 8, 18, 5, 5, 7),
- new DmParams(14, 14, 14, 14, 8, 8, 10),
- new DmParams(8, 32, 8, 16, 10, 10, 11),
- new DmParams(16, 16, 16, 16, 12, 12, 12),
- new DmParams(12, 26, 12, 26, 16, 16, 14),
- new DmParams(18, 18, 18, 18, 18, 18, 14),
- new DmParams(20, 20, 20, 20, 22, 22, 18),
- new DmParams(12, 36, 12, 18, 22, 22, 18),
- new DmParams(22, 22, 22, 22, 30, 30, 20),
- new DmParams(16, 36, 16, 18, 32, 32, 24),
- new DmParams(24, 24, 24, 24, 36, 36, 24),
- new DmParams(26, 26, 26, 26, 44, 44, 28),
- new DmParams(16, 48, 16, 24, 49, 49, 28),
- new DmParams(32, 32, 16, 16, 62, 62, 36),
- new DmParams(36, 36, 18, 18, 86, 86, 42),
- new DmParams(40, 40, 20, 20, 114, 114, 48),
- new DmParams(44, 44, 22, 22, 144, 144, 56),
- new DmParams(48, 48, 24, 24, 174, 174, 68),
- new DmParams(52, 52, 26, 26, 204, 102, 42),
- new DmParams(64, 64, 16, 16, 280, 140, 56),
- new DmParams(72, 72, 18, 18, 368, 92, 36),
- new DmParams(80, 80, 20, 20, 456, 114, 48),
- new DmParams(88, 88, 22, 22, 576, 144, 56),
- new DmParams(96, 96, 24, 24, 696, 174, 68),
- new DmParams(104, 104, 26, 26, 816, 136, 56),
- new DmParams(120, 120, 20, 20, 1050, 175, 68),
- new DmParams(132, 132, 22, 22, 1304, 163, 62),
- new DmParams(144, 144, 24, 24, 1558, 156, 62)};
-
- private static final String x12 = "\r*> 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ public static final String DEFAULT_DATA_MATRIX_ENCODING = "iso-8859-1";
+
+ private static final byte LATCH_B256 = (byte) 231;
+
+ private static final byte LATCH_EDIFACT = (byte) 240;
+
+ private static final byte LATCH_X12 = (byte) 238;
+
+ private static final byte LATCH_TEXT = (byte) 239;
+
+ private static final byte LATCH_C40 = (byte) 230;
+
+ private static final byte UNLATCH = (byte) 254;
+
+ private static final byte EXTENDED_ASCII = (byte) 235;
+
+ private static final byte PADDING = (byte) 129;
+
+ private String encoding;
+
+ private static final DmParams[] dmSizes = {
+ new DmParams(10, 10, 10, 10, 3, 3, 5),
+ new DmParams(12, 12, 12, 12, 5, 5, 7),
+ new DmParams(8, 18, 8, 18, 5, 5, 7),
+ new DmParams(14, 14, 14, 14, 8, 8, 10),
+ new DmParams(8, 32, 8, 16, 10, 10, 11),
+ new DmParams(16, 16, 16, 16, 12, 12, 12),
+ new DmParams(12, 26, 12, 26, 16, 16, 14),
+ new DmParams(18, 18, 18, 18, 18, 18, 14),
+ new DmParams(20, 20, 20, 20, 22, 22, 18),
+ new DmParams(12, 36, 12, 18, 22, 22, 18),
+ new DmParams(22, 22, 22, 22, 30, 30, 20),
+ new DmParams(16, 36, 16, 18, 32, 32, 24),
+ new DmParams(24, 24, 24, 24, 36, 36, 24),
+ new DmParams(26, 26, 26, 26, 44, 44, 28),
+ new DmParams(16, 48, 16, 24, 49, 49, 28),
+ new DmParams(32, 32, 16, 16, 62, 62, 36),
+ new DmParams(36, 36, 18, 18, 86, 86, 42),
+ new DmParams(40, 40, 20, 20, 114, 114, 48),
+ new DmParams(44, 44, 22, 22, 144, 144, 56),
+ new DmParams(48, 48, 24, 24, 174, 174, 68),
+ new DmParams(52, 52, 26, 26, 204, 102, 42),
+ new DmParams(64, 64, 16, 16, 280, 140, 56),
+ new DmParams(72, 72, 18, 18, 368, 92, 36),
+ new DmParams(80, 80, 20, 20, 456, 114, 48),
+ new DmParams(88, 88, 22, 22, 576, 144, 56),
+ new DmParams(96, 96, 24, 24, 696, 174, 68),
+ new DmParams(104, 104, 26, 26, 816, 136, 56),
+ new DmParams(120, 120, 20, 20, 1050, 175, 68),
+ new DmParams(132, 132, 22, 22, 1304, 163, 62),
+ new DmParams(144, 144, 24, 24, 1558, 156, 62)};
+
+ private static final String X12 = "\r*> 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private int extOut;
private short[] place;
private byte[] image;
@@ -155,12 +182,28 @@ public class BarcodeDatamatrix {
private int width;
private int ws;
private int options;
+ // value f[i][j] is the optimal amount of bytes required to encode substring(0, j)
+ private static int[][] f;
+ // switchMode[i][j] = k means that when encoding j-th symbol with mode = i + 1,
+ // we have to encode the previous symbol with mode = k in order to get optimal f[i][j] value
+ private static int[][] switchMode;
+
private boolean forceSquareSize = false;
/**
* Creates an instance of this class.
*/
- public BarcodeDatamatrix() {
+ public BarcodeDatamatrix() { encoding = DEFAULT_DATA_MATRIX_ENCODING; }
+
+ public BarcodeDatamatrix(String code) throws UnsupportedEncodingException {
+ encoding = DEFAULT_DATA_MATRIX_ENCODING;
+ generate(code);
+
+ }
+
+ public BarcodeDatamatrix(String code, String encoding) throws UnsupportedEncodingException {
+ this.encoding = encoding;
+ generate(code);
}
private void setBit(int x, int y, int xByte) {
@@ -214,7 +257,7 @@ private static void makePadding(byte[] data, int position, int count) {
//already in ascii mode
if (count <= 0)
return;
- data[position++] = (byte)129;
+ data[position++] = PADDING;
while (--count > 0) {
int t = 129 + (position + 1) * 149 % 253 + 1;
if (t > 254)
@@ -227,66 +270,99 @@ private static boolean isDigit(int c) {
return c >= '0' && c <= '9';
}
- private static int asciiEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) {
+ // when symbolIndex is non-negative, textLength should equal 1. All other encodations behave the same way.
+ private static int asciiEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength, int symbolIndex, int prevEnc, int origDataOffset) {
int ptrIn, ptrOut, c;
ptrIn = textOffset;
ptrOut = dataOffset;
textLength += textOffset;
dataLength += dataOffset;
while (ptrIn < textLength) {
+ c = text[ptrIn++] & 0xff;
+ if (isDigit(c) && symbolIndex > 0 && prevEnc == DM_ASCII && isDigit(text[ptrIn - 2] & 0xff)
+ && data[dataOffset - 1] > 48 && data[dataOffset - 1] < 59) {
+ data[ptrOut - 1] = (byte) (((text[ptrIn - 2] & 0xff) - '0') * 10 + c - '0' + 130);
+ return ptrOut - origDataOffset;
+ }
if (ptrOut >= dataLength)
return -1;
- c = text[ptrIn++] & 0xff;
- if (isDigit(c) && ptrIn < textLength && isDigit(text[ptrIn] & 0xff)) {
+
+ if (isDigit(c) && symbolIndex < 0 && ptrIn < textLength && isDigit(text[ptrIn] & 0xff)) {
data[ptrOut++] = (byte)((c - '0') * 10 + (text[ptrIn++] & 0xff) - '0' + 130);
}
else if (c > 127) {
if (ptrOut + 1 >= dataLength)
return -1;
- data[ptrOut++] = (byte)235;
+ data[ptrOut++] = EXTENDED_ASCII;
data[ptrOut++] = (byte)(c - 128 + 1);
}
else {
data[ptrOut++] = (byte)(c + 1);
}
}
- return ptrOut - dataOffset;
+ return ptrOut - origDataOffset;
}
- private static int b256Encodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) {
- int k, j, prn, tv, c;
+ private static int b256Encodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength,int symbolIndex, int prevEnc, int origDataOffset) {
+ int minRequiredDataIncrement;
if (textLength == 0)
return 0;
- if (textLength < 250 && textLength + 2 > dataLength)
- return -1;
- if (textLength >= 250 && textLength + 3 > dataLength)
- return -1;
- data[dataOffset] = (byte)231;
+ int simulatedDataOffset = dataOffset;
+ if (prevEnc != DM_B256) {
+ if (textLength < 250 && textLength + 2 > dataLength)
+ return -1;
+ if (textLength >= 250 && textLength + 3 > dataLength)
+ return -1;
+ data[dataOffset] = LATCH_B256;
+ } else {
+ int latestModeEntry = symbolIndex - 1;
+ while (latestModeEntry > 0 && switchMode[DM_B256 - 1][latestModeEntry] == DM_B256) {
+ latestModeEntry--;
+ }
+ textLength = symbolIndex - latestModeEntry + 1;
+ if (textLength != 250 && 1 > dataLength)
+ return -1;
+ if (textLength == 250 && 2 > dataLength)
+ return -1;
+ simulatedDataOffset -= (textLength - 1) + (textLength < 250 ? 2 : 3);
+ }
if (textLength < 250) {
- data[dataOffset + 1] = (byte)textLength;
- k = 2;
+ data[simulatedDataOffset + 1] = (byte) textLength;
+ minRequiredDataIncrement = prevEnc != DM_B256 ? 2 : 0;
+ } else if (textLength == 250 && prevEnc == DM_B256) {
+ data[simulatedDataOffset + 1] = (byte) (textLength / 250 + 249);
+ for (int i = dataOffset + 1; i > simulatedDataOffset + 2; i--)
+ data[i] = data[i - 1];
+ data[simulatedDataOffset + 2] = (byte) (textLength % 250);
+ minRequiredDataIncrement = 1;
+ } else {
+ data[simulatedDataOffset + 1] = (byte) (textLength / 250 + 249);
+ data[simulatedDataOffset + 2] = (byte) (textLength % 250);
+ minRequiredDataIncrement = prevEnc != DM_B256 ? 3 : 0;
}
- else {
- data[dataOffset + 1] = (byte)(textLength / 250 + 249);
- data[dataOffset + 2] = (byte)(textLength % 250);
- k = 3;
+ if (prevEnc == DM_B256)
+ textLength = 1;
+ System.arraycopy(text, textOffset, data, minRequiredDataIncrement + dataOffset, textLength);
+ for (int j = prevEnc != DM_B256 ? dataOffset + 1 : dataOffset; j < minRequiredDataIncrement + textLength + dataOffset; ++j) {
+ randomizationAlgorithm255(data, j);
}
- System.arraycopy(text, textOffset, data, k + dataOffset, textLength);
- k += textLength + dataOffset;
- for (j = dataOffset + 1; j < k; ++j) {
- c = data[j] & 0xff;
- prn = 149 * (j + 1) % 255 + 1;
- tv = c + prn;
- if (tv > 255)
- tv -= 256;
- data[j] = (byte)tv;
+ if (prevEnc == DM_B256)
+ randomizationAlgorithm255(data, simulatedDataOffset + 1);
+ return textLength + dataOffset + minRequiredDataIncrement - origDataOffset;
+ }
- }
- return k - dataOffset;
+ private static void randomizationAlgorithm255(byte[] data, int j) {
+ int c = data[j] & 0xff;
+ int prn = 149 * (j + 1) % 255 + 1;
+ int tv = c + prn;
+ if (tv > 255)
+ tv -= 256;
+ data[j] = (byte) tv;
}
- private static int X12Encodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) {
- int ptrIn, ptrOut, count, k, n, ci;
+ private static int X12Encodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength, int symbolIndex, int prevEnc, int origDataOffset) {
+ int ptrIn, ptrOut, count, k, n;
+ boolean latch = true;
byte c;
if (textLength == 0)
return 0;
@@ -295,12 +371,11 @@ private static int X12Encodation(byte[] text, int textOffset, int textLength, by
byte[] x = new byte[textLength];
count = 0;
for (; ptrIn < textLength; ++ptrIn) {
- int i = x12.indexOf((char)text[ptrIn + textOffset]);
+ int i = X12.indexOf((char) text[ptrIn + textOffset]);
if (i >= 0) {
- x[ptrIn] = (byte)i;
+ x[ptrIn] = (byte) i;
++count;
- }
- else {
+ } else {
x[ptrIn] = 100;
if (count >= 6)
count -= count / 3 * 3;
@@ -317,42 +392,78 @@ private static int X12Encodation(byte[] text, int textOffset, int textLength, by
c = 0;
for (; ptrIn < textLength; ++ptrIn) {
c = x[ptrIn];
- if (ptrOut >= dataLength)
+ if (ptrOut > dataLength)
break;
if (c < 40) {
- if (ptrIn == 0 || ptrIn > 0 && x[ptrIn - 1] > 40)
- data[dataOffset + ptrOut++] = (byte)238;
+ if (ptrIn == 0 && latch || ptrIn > 0 && x[ptrIn - 1] > 40)
+ data[dataOffset + ptrOut++] = LATCH_X12;
if (ptrOut + 2 > dataLength)
break;
n = 1600 * x[ptrIn] + 40 * x[ptrIn + 1] + x[ptrIn + 2] + 1;
- data[dataOffset + ptrOut++] = (byte)(n / 256);
- data[dataOffset + ptrOut++] = (byte)n;
+ data[dataOffset + ptrOut++] = (byte) (n / 256);
+ data[dataOffset + ptrOut++] = (byte) n;
ptrIn += 2;
- }
- else {
- if (ptrIn > 0 && x[ptrIn - 1] < 40)
- data[dataOffset + ptrOut++] = (byte)254;
- ci = text[ptrIn + textOffset] & 0xff;
- if (ci > 127) {
- data[dataOffset + ptrOut++] = (byte)235;
- ci -= 128;
+ } else {
+ boolean enterASCII = true;
+ if (symbolIndex <= 0) {
+ if (ptrIn > 0 && x[ptrIn - 1] < 40)
+ data[dataOffset + ptrOut++] = UNLATCH;
+ } else if (symbolIndex > 4 && prevEnc == DM_X12 && X12.indexOf((char) text[textOffset]) >= 0 && X12.indexOf((char) text[textOffset - 1]) >= 0) {
+ int latestModeEntry = symbolIndex - 1;
+ while (latestModeEntry > 0 && switchMode[DM_X12 - 1][latestModeEntry] == DM_X12
+ && (X12.indexOf((char) text[textOffset - (symbolIndex - latestModeEntry + 1)])) >= 0) {
+ latestModeEntry--;
+ }
+ int unlatch = -1;
+ if (symbolIndex - latestModeEntry >= 5) {
+ for (int i = 1; i <= symbolIndex - latestModeEntry; i++) {
+ if (data[dataOffset - i] == UNLATCH) {
+ unlatch = dataOffset - i;
+ break;
+ }
+ }
+ int amountOfEncodedWithASCII = unlatch >= 0 ? dataOffset - unlatch - 1 : symbolIndex - latestModeEntry;
+ if (amountOfEncodedWithASCII % 3 == 2) {
+ enterASCII = false;
+ textLength = amountOfEncodedWithASCII + 1;
+ textOffset -= amountOfEncodedWithASCII;
+ dataLength += unlatch < 0 ? amountOfEncodedWithASCII : amountOfEncodedWithASCII + 1;
+ dataOffset -= unlatch < 0 ? amountOfEncodedWithASCII : amountOfEncodedWithASCII + 1;
+ ptrIn = -1;
+ latch = unlatch != dataOffset;
+ x = new byte[amountOfEncodedWithASCII + 1];
+ for (int i = 0; i <= amountOfEncodedWithASCII; i++) {
+ x[i] = (byte) X12.indexOf((char) text[textOffset + i]);
+ }
+ } else {
+ x = new byte[1];
+ x[0] = 100;
+ }
+ }
+ }
+ if (enterASCII) {
+ int i = asciiEncodation(text, textOffset + ptrIn, 1, data, dataOffset + ptrOut, dataLength, -1, -1, origDataOffset);
+ if (i < 0)
+ return -1;
+ if (data[dataOffset + ptrOut] == EXTENDED_ASCII)
+ ptrOut++;
+ ptrOut++;
}
- if (ptrOut >= dataLength)
- break;
- data[dataOffset + ptrOut++] = (byte)(ci + 1);
}
}
c = 100;
if (textLength > 0)
c = x[textLength - 1];
- if (ptrIn != textLength || c < 40 && ptrOut >= dataLength)
+ if (ptrIn != textLength)
return -1;
if (c < 40)
- data[dataOffset + ptrOut++] = (byte)254;
- return ptrOut;
+ data[dataOffset + ptrOut++] = UNLATCH;
+ if (ptrOut > dataLength)
+ return -1;
+ return ptrOut + dataOffset - origDataOffset;
}
- private static int EdifactEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) {
+ private static int EdifactEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength,int symbolIndex, int prevEnc, int origDataOffset, boolean sizeFixed) {
int ptrIn, ptrOut, edi, pedi, c;
if (textLength == 0)
return 0;
@@ -361,13 +472,138 @@ private static int EdifactEncodation(byte[] text, int textOffset, int textLength
edi = 0;
pedi = 18;
boolean ascii = true;
+ int latestModeEntryActual = -1, latestModeEntryC40orX12 = -1, prevMode = -1;
+ if (prevEnc == DM_EDIFACT && ((text[textOffset] & 0xff & 0xe0) == 0x40 || (text[textOffset] & 0xff & 0xe0) == 0x20) && (text[textOffset] & 0xff) != '_'
+ && ((text[textOffset - 1] & 0xff & 0xe0) == 0x40 || (text[textOffset - 1] & 0xff & 0xe0) == 0x20) && (text[textOffset - 1] & 0xff) != '_') {
+ latestModeEntryActual = symbolIndex - 1;
+ while (latestModeEntryActual > 0 && switchMode[DM_EDIFACT - 1][latestModeEntryActual] == DM_EDIFACT) {
+ c = text[textOffset - (symbolIndex - latestModeEntryActual + 1)] & 0xff;
+ if (((c & 0xe0) == 0x40 || (c & 0xe0) == 0x20) && c != '_') {
+ latestModeEntryActual--;
+ } else
+ break;
+ }
+ prevMode = switchMode[DM_EDIFACT - 1][latestModeEntryActual] == DM_C40
+ || switchMode[DM_EDIFACT - 1][latestModeEntryActual] == DM_X12 ? switchMode[DM_EDIFACT - 1][latestModeEntryActual] : -1;
+ if (prevMode > 0)
+ latestModeEntryC40orX12 = latestModeEntryActual;
+ while (prevMode > 0 && latestModeEntryC40orX12 > 0 && switchMode[prevMode - 1][latestModeEntryC40orX12] == prevMode) {
+ c = text[textOffset - (symbolIndex - latestModeEntryC40orX12 + 1)] & 0xff;
+ if (((c & 0xe0) == 0x40 || (c & 0xe0) == 0x20) && c != '_') {
+ latestModeEntryC40orX12--;
+ } else {
+ latestModeEntryC40orX12 = -1;
+ break;
+ }
+ }
+ }
+ int dataSize = dataOffset + dataLength;
+ boolean asciiOneSymbol = false;
+ if (symbolIndex != -1)
+ asciiOneSymbol = true;
+ int dataTaken = 0, dataRequired = 0;
+ if (latestModeEntryC40orX12 >= 0 && symbolIndex - latestModeEntryC40orX12 + 1 > 9) {
+ textLength = symbolIndex - latestModeEntryC40orX12 + 1;
+ dataTaken = 0;
+ dataRequired = 0;
+ dataRequired += 1 + (textLength / 4 * 3);
+ if (!sizeFixed && (symbolIndex == text.length - 1 || symbolIndex < 0) && textLength % 4 < 3) {
+ dataSize = Integer.MAX_VALUE;
+ for (int i = 0; i < dmSizes.length; ++i) {
+ if (dmSizes[i].dataSize >= dataRequired + textLength % 4) {
+ dataSize = dmSizes[i].dataSize;
+ break;
+ }
+ }
+ }
+ if (dataSize - dataOffset - dataRequired <= 2 && textLength % 4 <= 2)
+ dataRequired += (textLength % 4);
+ else {
+ dataRequired += (textLength % 4) + 1;
+ if (textLength % 4 == 3)
+ dataRequired--;
+ }
+ for (int i = dataOffset - 1; i >= 0; i--) {
+ dataTaken++;
+ if (data[i] == (prevMode == DM_C40 ? LATCH_C40 : LATCH_X12)) {
+ break;
+ }
+ }
+ if (dataRequired <= dataTaken) {
+ asciiOneSymbol = false;
+ textOffset -= textLength - 1;
+ dataOffset -= dataTaken;
+ dataLength += dataTaken;
+ }
+ } else if (latestModeEntryActual >= 0 && symbolIndex - latestModeEntryActual + 1 > 9) {
+ textLength = symbolIndex - latestModeEntryActual + 1;
+ dataRequired += 1 + (textLength / 4 * 3);
+ if (dataSize - dataOffset - dataRequired <= 2 && textLength % 4 <= 2)
+ dataRequired += (textLength % 4);
+ else {
+ dataRequired += (textLength % 4) + 1;
+ if (textLength % 4 == 3)
+ dataRequired--;
+ }
+ int dataNewOffset = 0;
+ int latchEdi = -1;
+ for (int i = origDataOffset; i < dataOffset; i++)
+ if (data[i] == LATCH_EDIFACT && dataOffset - i <= dataRequired) {
+ latchEdi = i;
+ break;
+ }
+ if (latchEdi != -1) {
+ dataTaken += dataOffset - latchEdi;
+ if ((text[textOffset] & 0xff) > 127)
+ dataTaken += 2;
+ else {
+ if (isDigit(text[textOffset] & 0xff) && isDigit(text[textOffset - 1] & 0xff) &&
+ data[dataOffset - 1] >= 49 && data[dataOffset - 1] <= 58) {
+ dataTaken--;
+ }
+ dataTaken++;
+ }
+ dataNewOffset = dataOffset - latchEdi;
+ } else {
+ for (int j = symbolIndex - latestModeEntryActual; j >= 0; j--) {
+ if ((text[textOffset - j] & 0xff) > 127)
+ dataTaken += 2;
+ else {
+ if (j > 0 && isDigit(text[textOffset - j] & 0xff) && isDigit(text[textOffset - j + 1] & 0xff)) {
+ if (j == 1)
+ dataNewOffset = dataTaken;
+ j--;
+ }
+ dataTaken++;
+ }
+ if (j == 1)
+ dataNewOffset = dataTaken;
+ }
+ }
+ if (dataRequired <= dataTaken) {
+ asciiOneSymbol = false;
+ textOffset -= textLength - 1;
+ dataOffset -= dataNewOffset;
+ dataLength += dataNewOffset;
+ }
+ }
+ if (asciiOneSymbol) {
+ c = text[textOffset] & 0xff;
+ if (isDigit(c) && textOffset + ptrIn > 0 && isDigit(text[textOffset - 1] & 0xff)
+ && prevEnc == DM_EDIFACT && data[dataOffset - 1] >= 49 && data[dataOffset - 1] <= 58) {
+ data[dataOffset + ptrOut - 1] = (byte) (((text[textOffset - 1] & 0xff) - '0') * 10 + c - '0' + 130);
+ return dataOffset - origDataOffset;
+ } else {
+ return asciiEncodation(text, textOffset + ptrIn, 1, data, dataOffset + ptrOut, dataLength, -1, -1, origDataOffset);
+ }
+ }
for (; ptrIn < textLength; ++ptrIn) {
c = text[ptrIn + textOffset] & 0xff;
if (((c & 0xe0) == 0x40 || (c & 0xe0) == 0x20) && c != '_') {
if (ascii) {
if (ptrOut + 1 > dataLength)
break;
- data[dataOffset + ptrOut++] = (byte)240;
+ data[dataOffset + ptrOut++] = LATCH_EDIFACT;
ascii = false;
}
c &= 0x3f;
@@ -375,96 +611,181 @@ private static int EdifactEncodation(byte[] text, int textOffset, int textLength
if (pedi == 0) {
if (ptrOut + 3 > dataLength)
break;
- data[dataOffset + ptrOut++] = (byte)(edi >> 16);
- data[dataOffset + ptrOut++] = (byte)(edi >> 8);
- data[dataOffset + ptrOut++] = (byte)edi;
+ data[dataOffset + ptrOut++] = (byte) (edi >> 16);
+ data[dataOffset + ptrOut++] = (byte) (edi >> 8);
+ data[dataOffset + ptrOut++] = (byte) edi;
edi = 0;
pedi = 18;
- }
- else
+ } else
pedi -= 6;
} else {
if (!ascii) {
edi |= ('_' & 0x3f) << pedi;
if (ptrOut + 3 - pedi / 8 > dataLength)
break;
- data[dataOffset + ptrOut++] = (byte)(edi >> 16);
+ data[dataOffset + ptrOut++] = (byte) (edi >> 16);
if (pedi <= 12)
- data[dataOffset + ptrOut++] = (byte)(edi >> 8);
+ data[dataOffset + ptrOut++] = (byte) (edi >> 8);
if (pedi <= 6)
- data[dataOffset + ptrOut++] = (byte)edi;
+ data[dataOffset + ptrOut++] = (byte) edi;
ascii = true;
pedi = 18;
edi = 0;
}
- if (c > 127) {
- if (ptrOut >= dataLength)
- break;
- data[dataOffset + ptrOut++] = (byte)235;
- c -= 128;
+ if (isDigit(c) && textOffset + ptrIn > 0 && isDigit(text[textOffset + ptrIn - 1] & 0xff) &&
+ prevEnc == DM_EDIFACT && data[dataOffset - 1] >= 49 && data[dataOffset - 1] <= 58) {
+ data[dataOffset + ptrOut - 1] = (byte) (((text[textOffset - 1] & 0xff) - '0') * 10 + c - '0' + 130);
+ ptrOut--;
+ } else {
+ int i = asciiEncodation(text, textOffset + ptrIn, 1, data, dataOffset + ptrOut, dataLength, -1, -1, origDataOffset);
+ if (i < 0)
+ return -1;
+ if (data[dataOffset + ptrOut] == EXTENDED_ASCII)
+ ptrOut++;
+ ptrOut++;
}
- if (ptrOut >= dataLength)
- break;
- data[dataOffset + ptrOut++] = (byte)(c + 1);
}
}
if (ptrIn != textLength)
return -1;
- int dataSize = Integer.MAX_VALUE;
- for (int i = 0; i < dmSizes.length; ++i) {
- if (dmSizes[i].dataSize >= dataOffset + ptrOut + (3-pedi/6)) {
- dataSize = dmSizes[i].dataSize;
- break;
+ if (!sizeFixed && (symbolIndex == text.length - 1 || symbolIndex < 0)) {
+ dataSize = Integer.MAX_VALUE;
+ for (int i = 0; i < dmSizes.length; ++i) {
+ if (dmSizes[i].dataSize >= dataOffset + ptrOut + (3 - pedi / 6)) {
+ dataSize = dmSizes[i].dataSize;
+ break;
+ }
}
}
-
if (dataSize - dataOffset - ptrOut <= 2 && pedi >= 6) {
- //have to write up to 2 bytes and up to 2 symbols
+ if (pedi != 18 && ptrOut + 2 - pedi / 8 > dataLength)
+ return -1;
if (pedi <= 12) {
byte val = (byte) ((edi >> 18) & 0x3F);
if ((val & 0x20) == 0)
val |= 0x40;
- data[dataOffset + ptrOut++] = (byte)(val + 1);
+ data[dataOffset + ptrOut++] = (byte) (val + 1);
}
if (pedi <= 6) {
byte val = (byte) ((edi >> 12) & 0x3F);
if ((val & 0x20) == 0)
val |= 0x40;
- data[dataOffset + ptrOut++] = (byte)(val + 1);
+ data[dataOffset + ptrOut++] = (byte) (val + 1);
}
} else if (!ascii) {
edi |= ('_' & 0x3f) << pedi;
if (ptrOut + 3 - pedi / 8 > dataLength)
return -1;
- data[dataOffset + ptrOut++] = (byte)(edi >> 16);
+ data[dataOffset + ptrOut++] = (byte) (edi >> 16);
if (pedi <= 12)
- data[dataOffset + ptrOut++] = (byte)(edi >> 8);
+ data[dataOffset + ptrOut++] = (byte) (edi >> 8);
if (pedi <= 6)
- data[dataOffset + ptrOut++] = (byte)edi;
+ data[dataOffset + ptrOut++] = (byte) edi;
}
- return ptrOut;
+ return ptrOut + dataOffset - origDataOffset;
}
- private static int C40OrTextEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength, boolean c40) {
+
+ private static int C40OrTextEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength, boolean c40, int symbolIndex, int prevEnc, int origDataOffset) {
int ptrIn, ptrOut, encPtr, last0, last1, i, a, c;
String basic, shift2, shift3;
if (textLength == 0)
return 0;
ptrIn = 0;
ptrOut = 0;
- if (c40)
- data[dataOffset + ptrOut++] = (byte)230;
- else
- data[dataOffset + ptrOut++] = (byte)239;
shift2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_";
if (c40) {
basic = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
shift3 = "`abcdefghijklmnopqrstuvwxyz{|}~\177";
- }
- else {
+ } else {
basic = " 0123456789abcdefghijklmnopqrstuvwxyz";
shift3 = "`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\177";
}
+ boolean addLatch = true, usingASCII = false;
+ int mode = c40 ? DM_C40 : DM_TEXT;
+ if (prevEnc == mode) {
+ usingASCII = true;
+ int latestModeEntry = symbolIndex - 1;
+ while (latestModeEntry > 0 && switchMode[mode - 1][latestModeEntry] == mode) {
+ latestModeEntry--;
+ }
+ int unlatch = -1;
+ int dataAmountOfEncodedWithASCII = 0;
+ if (symbolIndex - latestModeEntry >= 5) {
+ for (i = symbolIndex - latestModeEntry; i > 0; i--) {
+ c = text[textOffset - i] & 0xff;
+ if (c > 127) {
+ dataAmountOfEncodedWithASCII += 2;
+ } else
+ dataAmountOfEncodedWithASCII++;
+ }
+ for (i = 1; i <= dataAmountOfEncodedWithASCII; i++) {
+ if (i > dataOffset)
+ break;
+ if (data[dataOffset - i] == UNLATCH) {
+ unlatch = dataOffset - i;
+ break;
+ }
+ }
+ int amountOfEncodedWithASCII = 0;
+ if (unlatch >= 0)
+ for (i = unlatch + 1; i < dataOffset; i++) {
+ if (data[i] == EXTENDED_ASCII)
+ i++;
+ if (data[i] >= -127 && data[i] <= -27)
+ amountOfEncodedWithASCII++;
+ amountOfEncodedWithASCII++;
+ }
+ else
+ amountOfEncodedWithASCII = symbolIndex - latestModeEntry;
+ int dataOffsetNew = 0;
+ for (i = amountOfEncodedWithASCII; i > 0; i--) {
+ int requiredCapacityForASCII = 0;
+ int requiredCapacityForC40orText = 0;
+ for (int j = i; j >= 0; j--) {
+ c = text[textOffset - j] & 0xff;
+ if (c > 127) {
+ c -= 128;
+ requiredCapacityForC40orText += 2;
+ }
+ requiredCapacityForC40orText += basic.indexOf((char) c) >= 0 ? 1 : 2;
+ if (c > 127)
+ requiredCapacityForASCII += 2;
+ else {
+ if (j > 0 && isDigit(c) && isDigit(text[textOffset - j + 1] & 0xff)) {
+ requiredCapacityForC40orText += basic.indexOf((char) text[textOffset - j + 1]) >= 0 ? 1 : 2;
+ j--;
+ dataOffsetNew = requiredCapacityForASCII + 1;
+ }
+ requiredCapacityForASCII++;
+ }
+ if (j == 1)
+ dataOffsetNew = requiredCapacityForASCII;
+ }
+ addLatch = unlatch < 0 ? true : (dataOffset - requiredCapacityForASCII != unlatch);
+ if (requiredCapacityForC40orText % 3 == 0 &&
+ requiredCapacityForC40orText / 3 * 2 + (addLatch ? 2 : 0) < requiredCapacityForASCII) {
+ usingASCII = false;
+ textLength = i + 1;
+ textOffset -= i;
+ dataOffset -= addLatch ? dataOffsetNew : dataOffsetNew + 1;
+ dataLength += addLatch ? dataOffsetNew : dataOffsetNew + 1;
+ break;
+ }
+ if (isDigit(text[textOffset - i] & 0xff) && isDigit(text[textOffset - i + 1] & 0xff))
+ i--;
+ }
+ }
+ } else if (symbolIndex != -1)
+ usingASCII = true;
+ if (usingASCII)
+ return asciiEncodation(text, textOffset, 1, data, dataOffset, dataLength, prevEnc == mode ? 1 : -1, DM_ASCII, origDataOffset);
+ if (addLatch) {
+ if (c40)
+ data[dataOffset + ptrOut++] = LATCH_C40;
+ else
+ data[dataOffset + ptrOut++] = LATCH_TEXT;
+ }
int[] enc = new int[textLength * 4 + 10];
encPtr = 0;
last0 = 0;
@@ -480,19 +801,16 @@ private static int C40OrTextEncodation(byte[] text, int textOffset, int textLeng
enc[encPtr++] = 1;
enc[encPtr++] = 30;
}
- int idx = basic.indexOf((char)c);
+ int idx = basic.indexOf((char) c);
if (idx >= 0) {
enc[encPtr++] = idx + 3;
- }
- else if (c < 32) {
+ } else if (c < 32) {
enc[encPtr++] = 0;
enc[encPtr++] = c;
- }
- else if ((idx = shift2.indexOf((char)c)) >= 0) {
+ } else if ((idx = shift2.indexOf((char) c)) >= 0) {
enc[encPtr++] = 1;
enc[encPtr++] = idx;
- }
- else if ((idx = shift3.indexOf((char)c)) >= 0) {
+ } else if ((idx = shift3.indexOf((char) c)) >= 0) {
enc[encPtr++] = 2;
enc[encPtr++] = idx;
}
@@ -507,83 +825,126 @@ else if ((idx = shift3.indexOf((char)c)) >= 0) {
i = 0;
for (; i < encPtr; i += 3) {
a = 1600 * enc[i] + 40 * enc[i + 1] + enc[i + 2] + 1;
- data[dataOffset + ptrOut++] = (byte)(a / 256);
- data[dataOffset + ptrOut++] = (byte)a;
+ data[dataOffset + ptrOut++] = (byte) (a / 256);
+ data[dataOffset + ptrOut++] = (byte) a;
}
- data[ptrOut++] = (byte)254;
- i = asciiEncodation(text, ptrIn, textLength - ptrIn, data, ptrOut, dataLength - ptrOut);
- if (i < 0)
+ if (dataLength - ptrOut > 2)
+ data[dataOffset + ptrOut++] = UNLATCH;
+ if (symbolIndex < 0 && textLength > ptrIn) {
+ i = asciiEncodation(text, textOffset + ptrIn, textLength - ptrIn, data, dataOffset + ptrOut, dataLength - ptrOut, -1, -1, origDataOffset);
return i;
- return ptrOut + i;
+ }
+ return ptrOut + dataOffset - origDataOffset;
+ }
+
+
+ private static int minValueInColumn(int[][] array, int column) {
+ int min = Integer.MAX_VALUE;
+ for (int i = 0; i < 6; i++)
+ if (array[i][column] < min && array[i][column] >= 0)
+ min = array[i][column];
+ return min != Integer.MAX_VALUE ? min : -1;
}
- private static int getEncodation(byte[] text, int textOffset, int textSize, byte[] data, int dataOffset, int dataSize, int options, boolean firstMatch) {
- int e, j, k;
- int[] e1 = new int[6];
+ private static int valuePositionInColumn(int[][] array, int column, int value) {
+ for (int i = 0; i < 6; i++)
+ if (array[i][column] == value)
+ return i;
+ return -1;
+ }
+
+ private static void solveFAndSwitchMode(int[] forMin, int mode, int currIndex) {
+ if (forMin[mode] >= 0 && f[mode][currIndex - 1] >= 0) {
+ f[mode][currIndex] = forMin[mode];
+ switchMode[mode][currIndex] = mode + 1;
+ } else {
+ f[mode][currIndex] = Integer.MAX_VALUE;
+ }
+ for (int i = 0; i < 6; i++) {
+ if (forMin[i] < f[mode][currIndex] && forMin[i] >= 0 && f[i][currIndex - 1] >= 0) {
+ f[mode][currIndex] = forMin[i];
+ switchMode[mode][currIndex] = i + 1;
+ }
+ }
+ if (f[mode][currIndex] == Integer.MAX_VALUE) {
+ f[mode][currIndex] = -1;
+ }
+ }
+
+
+ private static int getEncodation(byte[] text, int textOffset, int textSize, byte[] data, int dataOffset, int dataSize, int options, boolean sizeFixed) {
+ int e;
if (dataSize < 0)
return -1;
- e = -1;
options &= 7;
if (options == 0) {
- e1[0] = asciiEncodation(text, textOffset, textSize, data, dataOffset, dataSize);
- if (firstMatch && e1[0] >= 0)
- return e1[0];
- e1[1] = C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, false);
- if (firstMatch && e1[1] >= 0)
- return e1[1];
- e1[2] = C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, true);
- if (firstMatch && e1[2] >= 0)
- return e1[2];
- e1[3] = b256Encodation(text, textOffset, textSize, data, dataOffset, dataSize);
- if (firstMatch && e1[3] >= 0)
- return e1[3];
- e1[4] = X12Encodation(text, textOffset, textSize, data, dataOffset, dataSize);
- if (firstMatch && e1[4] >= 0)
- return e1[4];
- e1[5] = EdifactEncodation(text, textOffset, textSize, data, dataOffset, dataSize);
- if (firstMatch && e1[5] >= 0)
- return e1[5];
- if (e1[0] < 0 && e1[1] < 0 && e1[2] < 0 && e1[3] < 0 && e1[4] < 0 && e1[5] < 0) {
- return -1;
+ if (textSize == 0)
+ return 0;
+ byte[][] dataDynamic = new byte[6][data.length];
+ for (int i = 0; i < 6; i++) {
+ System.arraycopy(data, 0, dataDynamic[i], 0, data.length);
+ switchMode[i][0] = i + 1;
}
- j = 0;
- e = 99999;
- for (k = 0; k < 6; ++k) {
- if (e1[k] >= 0 && e1[k] < e) {
- e = e1[k];
- j = k;
+ f[0][0] = asciiEncodation(text, textOffset, 1, dataDynamic[0], dataOffset, dataSize, 0, -1, dataOffset);
+ f[1][0] = C40OrTextEncodation(text, textOffset, 1, dataDynamic[1], dataOffset, dataSize, true, 0, -1, dataOffset);
+ f[2][0] = C40OrTextEncodation(text, textOffset, 1, dataDynamic[2], dataOffset, dataSize, false, 0, -1, dataOffset);
+ f[3][0] = b256Encodation(text, textOffset, 1, dataDynamic[3], dataOffset, dataSize, 0, -1, dataOffset);
+ f[4][0] = X12Encodation(text, textOffset, 1, dataDynamic[4], dataOffset, dataSize, 0, -1, dataOffset);
+ f[5][0] = EdifactEncodation(text, textOffset, 1, dataDynamic[5], dataOffset, dataSize, 0, -1, dataOffset, sizeFixed);
+ int[] dataNewOffset = new int[6];
+ for (int i = 1; i < textSize; i++) {
+ int tempForMin[] = new int[6];
+ for (int k = 0; k < 6; k++) {
+ dataNewOffset[k] = f[k][i - 1] >= 0 ? f[k][i - 1] : Integer.MAX_VALUE;
+ }
+ for (int currEnc = 0; currEnc < 6; currEnc++) {
+ byte[][] dataDynamicInner = new byte[6][data.length];
+ for (int prevEnc = 0; prevEnc < 6; prevEnc++) {
+ System.arraycopy(dataDynamic[prevEnc], 0, dataDynamicInner[prevEnc], 0, data.length);
+ if (currEnc == 0)
+ tempForMin[prevEnc] = asciiEncodation(text, textOffset + i, 1, dataDynamicInner[prevEnc], dataNewOffset[prevEnc] + dataOffset, dataSize - dataNewOffset[prevEnc], i, prevEnc + 1, dataOffset);
+ if (currEnc == 1)
+ tempForMin[prevEnc] = C40OrTextEncodation(text, textOffset + i, 1, dataDynamicInner[prevEnc], dataNewOffset[prevEnc] + dataOffset, dataSize - dataNewOffset[prevEnc], true, i, prevEnc + 1, dataOffset);
+ if (currEnc == 2)
+ tempForMin[prevEnc] = C40OrTextEncodation(text, textOffset + i, 1, dataDynamicInner[prevEnc], dataNewOffset[prevEnc] + dataOffset, dataSize - dataNewOffset[prevEnc], false, i, prevEnc + 1, dataOffset);
+ if (currEnc == 3)
+ tempForMin[prevEnc] = b256Encodation(text, textOffset + i, 1, dataDynamicInner[prevEnc], dataNewOffset[prevEnc] + dataOffset, dataSize - dataNewOffset[prevEnc], i, prevEnc + 1, dataOffset);
+ if (currEnc == 4)
+ tempForMin[prevEnc] = X12Encodation(text, textOffset + i, 1, dataDynamicInner[prevEnc], dataNewOffset[prevEnc] + dataOffset, dataSize - dataNewOffset[prevEnc], i, prevEnc + 1, dataOffset);
+ if (currEnc == 5)
+ tempForMin[prevEnc] = EdifactEncodation(text, textOffset + i, 1, dataDynamicInner[prevEnc], dataNewOffset[prevEnc] + dataOffset, dataSize - dataNewOffset[prevEnc], i, prevEnc + 1, dataOffset, sizeFixed);
+
+ }
+ solveFAndSwitchMode(tempForMin, currEnc, i);
+ if (switchMode[currEnc][i] != 0)
+ System.arraycopy(dataDynamicInner[switchMode[currEnc][i] - 1], 0, dataDynamic[currEnc], 0, data.length);
}
}
- if (j == 0)
- e = asciiEncodation(text, textOffset, textSize, data, dataOffset, dataSize);
- else if (j == 1)
- e = C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, false);
- else if (j == 2)
- e = C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, true);
- else if (j == 3)
- e = b256Encodation(text, textOffset, textSize, data, dataOffset, dataSize);
- else if (j == 4)
- e = X12Encodation(text, textOffset, textSize, data, dataOffset, dataSize);
+ e = minValueInColumn(f, textSize - 1);
+ if (e > dataSize || e < 0)
+ return -1;
+ int bestDataDynamicResultIndex = valuePositionInColumn(f, textSize - 1, e);
+ System.arraycopy(dataDynamic[bestDataDynamicResultIndex], 0, data, 0, data.length);
return e;
}
switch (options) {
- case DM_ASCII:
- return asciiEncodation(text, textOffset, textSize, data, dataOffset, dataSize);
- case DM_C40:
- return C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, true);
- case DM_TEXT:
- return C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, false);
- case DM_B256:
- return b256Encodation(text, textOffset, textSize, data, dataOffset, dataSize);
- case DM_X21:
- return X12Encodation(text, textOffset, textSize, data, dataOffset, dataSize);
- case DM_EDIFACT:
- return EdifactEncodation(text, textOffset, textSize, data, dataOffset, dataSize);
- case DM_RAW:
- if (textSize > dataSize)
- return -1;
- System.arraycopy(text, textOffset, data, dataOffset, textSize);
- return textSize;
+ case DM_ASCII:
+ return asciiEncodation(text, textOffset, textSize, data, dataOffset, dataSize, -1, -1, dataOffset);
+ case DM_C40:
+ return C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, true, -1, -1, dataOffset);
+ case DM_TEXT:
+ return C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, false, -1, -1, dataOffset);
+ case DM_B256:
+ return b256Encodation(text, textOffset, textSize, data, dataOffset, dataSize, -1, -1, dataOffset);
+ case DM_X12:
+ return X12Encodation(text, textOffset, textSize, data, dataOffset, dataSize, -1, -1, dataOffset);
+ case DM_EDIFACT:
+ return EdifactEncodation(text, textOffset, textSize, data, dataOffset, dataSize, -1, -1, dataOffset, sizeFixed);
+ case DM_RAW:
+ if (textSize > dataSize)
+ return -1;
+ System.arraycopy(text, textOffset, data, dataOffset, textSize);
+ return textSize;
}
return -1;
}
@@ -695,7 +1056,12 @@ else if (eci < 16383) {
* @throws java.io.UnsupportedEncodingException on error
*/
public int generate(String text) throws UnsupportedEncodingException {
- byte[] t = text.getBytes("iso-8859-1");
+ byte[] t;
+ try {
+ t = text.getBytes(encoding);
+ }catch (UnsupportedEncodingException exc) {
+ throw new IllegalArgumentException("text has to be encoded in iso-8859-1");
+ }
return generate(t, 0, t.length);
}
@@ -712,6 +1078,7 @@ public int generate(String text) throws UnsupportedEncodingException {
* DM_ERROR_EXTENSION - an error was while parsing an extension.
*/
public int generate(byte[] text, int textOffset, int textSize) {
+
int extCount, e, k, full;
DmParams dm, last;
byte[] data = new byte[2500];
@@ -721,6 +1088,8 @@ public int generate(byte[] text, int textOffset, int textSize) {
return DM_ERROR_EXTENSION;
}
e = -1;
+ f = new int[6][textSize - extOut];
+ switchMode = new int[6][textSize - extOut];
if (height == 0 || width == 0) {
last = dmSizes[dmSizes.length - 1];
e = getEncodation(text, textOffset + extOut, textSize - extOut, data, extCount, last.dataSize - extCount, options, false);
@@ -729,14 +1098,13 @@ public int generate(byte[] text, int textOffset, int textSize) {
}
e += extCount;
for (k = 0; k < dmSizes.length; ++k) {
- if (dmSizes[k].dataSize >= e && (!forceSquareSize || dmSizes[k].width == dmSizes[k].height))
+ if (dmSizes[k].dataSize >= e)
break;
}
dm = dmSizes[k];
height = dm.height;
width = dm.width;
- }
- else {
+ } else {
for (k = 0; k < dmSizes.length; ++k) {
if (height == dmSizes[k].height && width == dmSizes[k].width)
break;
diff --git a/itext/src/main/java/com/itextpdf/text/pdf/BaseFont.java b/itext/src/main/java/com/itextpdf/text/pdf/BaseFont.java
index a65f263f08..a37659d49a 100644
--- a/itext/src/main/java/com/itextpdf/text/pdf/BaseFont.java
+++ b/itext/src/main/java/com/itextpdf/text/pdf/BaseFont.java
@@ -1496,6 +1496,21 @@ public static ArrayList
*
* @author Palash Ray
*/
public class IndicCompositeCharacterComparator implements Comparator {
-
+
public int compare(String o1, String o2) {
- if (o2.length() > o1.length()) {
+ if (o1.length() < o2.length()) {
return 1;
- } else if (o1.length() > o2.length()) {
+ }
+ if (o1.length() > o2.length()) {
return -1;
- } else {
- return o1.compareTo(o2);
}
+ return o1.compareTo(o2);
}
}
diff --git a/itext/src/main/java/com/itextpdf/text/pdf/security/LtvVerifier.java b/itext/src/main/java/com/itextpdf/text/pdf/security/LtvVerifier.java
index f595246b20..6f5f5e5dc6 100644
--- a/itext/src/main/java/com/itextpdf/text/pdf/security/LtvVerifier.java
+++ b/itext/src/main/java/com/itextpdf/text/pdf/security/LtvVerifier.java
@@ -55,6 +55,7 @@
import java.util.Date;
import java.util.List;
+import com.itextpdf.text.log.Level;
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
import org.bouncycastle.cert.ocsp.OCSPException;
import org.bouncycastle.cert.ocsp.OCSPResp;
@@ -109,7 +110,9 @@ public LtvVerifier(PdfReader reader) throws GeneralSecurityException {
signatureName = names.get(names.size() - 1);
this.signDate = new Date();
pkcs7 = coversWholeDocument();
- LOGGER.info(String.format("Checking %ssignature %s", pkcs7.isTsp() ? "document-level timestamp " : "", signatureName));
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("Checking %ssignature %s", pkcs7.isTsp() ? "document-level timestamp " : "", signatureName));
+ }
}
/**
@@ -292,7 +295,9 @@ public void switchToPreviousRevision() throws IOException, GeneralSecurityExcept
names = fields.getSignatureNames();
signatureName = names.get(names.size() - 1);
pkcs7 = coversWholeDocument();
- LOGGER.info(String.format("Checking %ssignature %s", pkcs7.isTsp() ? "document-level timestamp " : "", signatureName));
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("Checking %ssignature %s", pkcs7.isTsp() ? "document-level timestamp " : "", signatureName));
+ }
}
else {
LOGGER.info("No signatures in revision");
diff --git a/itext/src/main/java/com/itextpdf/text/pdf/security/OCSPVerifier.java b/itext/src/main/java/com/itextpdf/text/pdf/security/OCSPVerifier.java
index 905c304958..20fc84cd41 100644
--- a/itext/src/main/java/com/itextpdf/text/pdf/security/OCSPVerifier.java
+++ b/itext/src/main/java/com/itextpdf/text/pdf/security/OCSPVerifier.java
@@ -56,6 +56,7 @@
import java.util.Enumeration;
import java.util.List;
+import com.itextpdf.text.log.Level;
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
@@ -170,10 +171,14 @@ public boolean verify(BasicOCSPResp ocspResp, X509Certificate signCert, X509Cert
Date nextUpdate = resp[i].getNextUpdate();
if (nextUpdate == null) {
nextUpdate = new Date(resp[i].getThisUpdate().getTime() + 180000l);
- LOGGER.info(String.format("No 'next update' for OCSP Response; assuming %s", nextUpdate));
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("No 'next update' for OCSP Response; assuming %s", nextUpdate));
+ }
}
if (signDate.after(nextUpdate)) {
- LOGGER.info(String.format("OCSP no longer valid: %s after %s", signDate, nextUpdate));
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("OCSP no longer valid: %s after %s", signDate, nextUpdate));
+ }
continue;
}
// check the status of the certificate
diff --git a/itext/src/main/java/com/itextpdf/text/pdf/security/TSAClientBouncyCastle.java b/itext/src/main/java/com/itextpdf/text/pdf/security/TSAClientBouncyCastle.java
index 38c8d74589..7a086ce338 100644
--- a/itext/src/main/java/com/itextpdf/text/pdf/security/TSAClientBouncyCastle.java
+++ b/itext/src/main/java/com/itextpdf/text/pdf/security/TSAClientBouncyCastle.java
@@ -44,21 +44,10 @@
package com.itextpdf.text.pdf.security;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.net.URL;
-import java.net.URLConnection;
-
import com.itextpdf.text.error_messages.MessageLocalization;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.pdf.codec.Base64;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.cmp.PKIFailureInfo;
import org.bouncycastle.tsp.TSPException;
@@ -68,6 +57,16 @@
import org.bouncycastle.tsp.TimeStampToken;
import org.bouncycastle.tsp.TimeStampTokenInfo;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+
/**
* Time Stamp Authority Client interface implementation using Bouncy Castle
* org.bouncycastle.tsp package.
@@ -105,7 +104,10 @@ public class TSAClientBouncyCastle implements TSAClient {
/** Hash algorithm */
protected String digestAlgorithm;
-
+
+ /** TSA request policy */
+ private String tsaReqPolicy = null;
+
/**
* Creates an instance of a TSAClient that will use BouncyCastle.
* @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
@@ -158,6 +160,14 @@ public int getTokenSizeEstimate() {
return tokenSizeEstimate;
}
+ public String getTSAReqPolicy() {
+ return tsaReqPolicy;
+ }
+
+ public void setTSAReqPolicy(String tsaReqPolicy) {
+ this.tsaReqPolicy = tsaReqPolicy;
+ }
+
/**
* Gets the MessageDigest to digest the data imprint
* @return the digest algorithm name
@@ -179,6 +189,9 @@ public byte[] getTimeStampToken(byte[] imprint) throws IOException, TSPException
// Setup the time stamp request
TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator();
tsqGenerator.setCertReq(true);
+ if (tsaReqPolicy != null && tsaReqPolicy.length() > 0) {
+ tsqGenerator.setReqPolicy(new ASN1ObjectIdentifier(tsaReqPolicy));
+ }
// tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
TimeStampRequest request = tsqGenerator.generate(new ASN1ObjectIdentifier(DigestAlgorithms.getAllowedDigests(digestAlgorithm)), imprint, nonce);
diff --git a/itext/src/main/java/com/itextpdf/text/xml/xmp/XmpReader.java b/itext/src/main/java/com/itextpdf/text/xml/xmp/XmpReader.java
index ed789a7721..b04daa804e 100644
--- a/itext/src/main/java/com/itextpdf/text/xml/xmp/XmpReader.java
+++ b/itext/src/main/java/com/itextpdf/text/xml/xmp/XmpReader.java
@@ -46,6 +46,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -55,6 +56,8 @@
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.itextpdf.text.ExceptionConverter;
@@ -96,6 +99,7 @@ public XmpReader(byte[] bytes) throws SAXException, IOException {
DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
fact.setNamespaceAware(true);
DocumentBuilder db = fact.newDocumentBuilder();
+ db.setEntityResolver(new SafeEmptyEntityResolver());
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
domDocument = db.parse(bais);
} catch (ParserConfigurationException e) {
@@ -219,4 +223,10 @@ public byte[] serializeDoc() throws IOException {
fout.close();
return fout.toByteArray();
}
+
+ private static class SafeEmptyEntityResolver implements EntityResolver {
+ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
+ return new InputSource(new StringReader(""));
+ }
+ }
}
diff --git a/itext/src/main/resources/com/itextpdf/text/l10n/error/en.lng b/itext/src/main/resources/com/itextpdf/text/l10n/error/en.lng
index 4686f1186c..032cef298e 100644
--- a/itext/src/main/resources/com/itextpdf/text/l10n/error/en.lng
+++ b/itext/src/main/resources/com/itextpdf/text/l10n/error/en.lng
@@ -74,6 +74,7 @@ an.uncolored.pattern.was.expected=An uncolored pattern was expected.
an.uncolored.tile.pattern.can.not.have.another.pattern.or.shading.as.color=An uncolored tile pattern can not have another pattern or shading as color.
annotation.of.type.1.should.have.contents.key=Annotation of type {1} should have Contents key.
annotation.type.1.not.allowed=Annotation type {1} not allowed.
+annotation.type.not.supported.flattening=This annotation is not supported for flattening. Skipping this annotation.
appearance.dictionary.of.widget.subtype.and.btn.field.type.shall.contain.only.the.n.key.with.dictionary.value=Appearance dictionary of Widget subtype and Btn field type shall contain only the n key with dictionary value
appearance.dictionary.shall.contain.only.the.n.key.with.stream.value=Appearance dictionary shall contain only the N key with stream value.
append.mode.does.not.support.changing.the.encryption.status=Append mode does not support changing the encryption status.
@@ -167,6 +168,7 @@ error.in.base64.code.reading.stream=Error in Base64 code reading stream.
error.parsing.cmap.beginbfchar.expected.cosstring.or.cosname.and.not.1=Error parsing CMap beginbfchar, expected {COSString or COSName} and not {1}
error.reading.objstm=Error reading ObjStm
error.reading.string=Error reading string
+error.resolving.freetext.font=Cannot resolve annotation's font. It won't be flattened
error.with.jp.marker=Error with JP Marker
every.annotation.shall.have.at.least.one.appearance.dictionary=Every annotation shall have at least one appearance dictionary
exactly.one.colour.space.specification.shall.have.the.value.0x01.in.the.approx.field=Exactly one colour space specification shall have the value 0x01 in the APPROX field.
@@ -194,6 +196,7 @@ font.1.with.2.is.not.recognized=Font '{1}' with '{2}' is not recognized.
font.and.size.must.be.set.before.writing.any.text=Font and size must be set before writing any text
font.size.too.small.1=Font size too small: {1}
fontfactoryimp.cannot.be.null=FontFactoryImp cannot be null.
+freetext.annotation.doesnt.contain.da=FreeText Annotation doesn't contain a DA. Not flattening this annotation.
freetext.flattening.is.not.supported.in.append.mode=FreeText flattening is not supported in append mode.
annotation.flattening.is.not.supported.in.append.mode=Annotation flattening is not supported in append mode.
getcell.at.illegal.index.1.max.is.2=getCell at illegal index :{1} max is {2}
@@ -272,6 +275,7 @@ it.is.not.possible.to.free.reader.in.merge.fields.mode=It is not possible to fre
java.awt.image.fetch.aborted.or.errored=java.awt.Image fetch aborted or errored
java.awt.image.interrupted.waiting.for.pixels=java.awt.Image Interrupted waiting for pixels!
jpeg2000.enumerated.colour.space.19.(CIEJab).shall.not.be.used=JPEG2000 enumerated colour space 19 (CIEJab) shall not be used.
+key.is.null=key is null.
keyword.encrypt.shall.not.be.used.in.the.trailer.dictionary=Keyword Encrypt shall not be used in the trailer dictionary.
lab.cs.black.point=The BlackPoint entry in Lab color space could be only an array of three numbers [XB YB ZB]. All three of these numbers shall be non-negative. Default value: [0.0 0.0 0.0].
lab.cs.range=The Range entry in Lab color space could be only an array of four numbers [amin amax bmin bmax]. Default value: [-100 100 -100 100].
@@ -392,6 +396,7 @@ stdcf.not.found.encryption=/StdCF not found (encryption)
stream.could.not.be.compressed.filter.is.not.a.name.or.array=Stream could not be compressed: filter is not a name or array.
stream.object.dictionary.shall.not.contain.the.f.ffilter.or.fdecodeparams.keys=Stream object dictionary shall not contain the F, FFilter or FDecodeParams keys.
structparent.not.found=StructParent not found.
+structparentid.not.found=StructParent ID not found.
support.only.sha1.hash.algorithm=Support only SHA1 hash algorithm.
support.only.rsa.and.dsa.algorithms=Support only RSA and DSA algorithms.
invalid.structparent=Invalid StructParent.
diff --git a/itext/src/main/resources/com/itextpdf/text/l10n/error/nl.lng b/itext/src/main/resources/com/itextpdf/text/l10n/error/nl.lng
index 45d943870b..2e92042c40 100644
--- a/itext/src/main/resources/com/itextpdf/text/l10n/error/nl.lng
+++ b/itext/src/main/resources/com/itextpdf/text/l10n/error/nl.lng
@@ -74,6 +74,7 @@ an.uncolored.pattern.was.expected=Er werd een ongekleurd patroon verwacht.
an.uncolored.tile.pattern.can.not.have.another.pattern.or.shading.as.color=Een ongekleurd tile pattern kan geen ander pattern of shading als color gebruiken.
annotation.of.type.1.should.have.contents.key=Annotation van type {1} moet een Contents sleutel hebben.
annotation.type.1.not.allowed=Annotation type {1} niet toegelaten.
+annotation.type.not.supported.flattening=Dit annotatie type is niet ondersteund tijdens het flattenen. Deze wordt overgeslaan.
appearance.dictionary.of.widget.subtype.and.btn.field.type.shall.contain.only.the.n.key.with.dictionary.value=Appearance dictionary van subtype Widget en field type Btn mag enkel de N sleutel met als waarde een Dictionaty bevatten
appearance.dictionary.shall.contain.only.the.n.key.with.stream.value=Appearance dictionary mag enkel de N sleutel met een stream waarde bevatten.
append.mode.does.not.support.changing.the.encryption.status=Append mode laat geen wijziging toe van de encryptie status.
@@ -167,6 +168,7 @@ error.in.base64.code.reading.stream=Fout in de Base64 code reading stream.
error.parsing.cmap.beginbfchar.expected.cosstring.or.cosname.and.not.1=Fout bij het parsen van CMap beginbfchar, {COSString or COSName} verwacht in plaats van {1}
error.reading.objstm=Fout tijdens het lezen van ObjStm
error.reading.string=Fout bij het lezen van een string
+error.resolving.freetext.font=Kan het lettertype van annotatie niet oplossen. Het wordt niet afgedrukt
error.with.jp.marker=Foute JP Marker
every.annotation.shall.have.at.least.one.appearance.dictionary=Elke annotation moet ten minste 1 appearance dictionary hebben
exactly.one.colour.space.specification.shall.have.the.value.0x01.in.the.approx.field=Exact 1 colour space specificatie moet de waarde 0x01 in het APPROX veld hebben.
@@ -194,6 +196,7 @@ font.1.with.2.is.not.recognized=Font '{1}' met '{2}' werd niet herkend.
font.and.size.must.be.set.before.writing.any.text=Font en size moeten bepaald zijn vooraleer je tekst schrijft.
font.size.too.small.1=Font size te klein: {1}
fontfactoryimp.cannot.be.null=FontFactoryImp kan niet null zijn.
+freetext.annotation.doesnt.contain.da=FreeText Annotatie bevat geen DA. Deze annotatie kan niet worden geflattened en wordt overgeslaan.
freetext.flattening.is.not.supported.in.append.mode=FreeText flattening is niet ondersteund in append mode.
annotation.flattening.is.not.supported.in.append.mode=Het flattenen van annotations is niet ondersteund in append mode.
getcell.at.illegal.index.1.max.is.2=getCell op ongeldige index:{1} maximum: {2}
@@ -272,6 +275,7 @@ it.is.not.possible.to.free.reader.in.merge.fields.mode=freeReader is niet mogeli
java.awt.image.fetch.aborted.or.errored=Ophalen van java.awt.Image afgebroken of misgelopen.
java.awt.image.interrupted.waiting.for.pixels=java.awt.Image onderbroken; aan het wachten op pixels!
jpeg2000.enumerated.colour.space.19.(CIEJab).shall.not.be.used=JPEG2000 enumerated colour space 19 (CIEJab) mag niet gebruikt worden.
+key.is.null=sleutel is nul.
keyword.encrypt.shall.not.be.used.in.the.trailer.dictionary=Keyword Encrypt mag niet gebruikt worden in de trailer dictionary.
lab.cs.black.point=De BlackPoint entry in Lab color space mag enkel een array zijn van drie getallen [XB YB ZB]. Al deze getallen moeten niet-negatief zijn. Standaardwaarde: [0.0 0.0 0.0].
lab.cs.range=De Range entry in Lab color space mag enkel een array zijn van vier getallen [amin amax bmin bmax]. Standaardwaarde: [-100 100 -100 100].
@@ -392,6 +396,7 @@ stdcf.not.found.encryption=/StdCF niet gevonden (encryption)
stream.could.not.be.compressed.filter.is.not.a.name.or.array=Stream kon niet gecomprimeerd worden: de filter is geen naam of array.
stream.object.dictionary.shall.not.contain.the.f.ffilter.or.fdecodeparams.keys=Stream object dictionary mag geen F, FFilter of FDecodeParams sleutels bevatten.
structparent.not.found=StructParent niet gevonden.
+structparentid.not.found=StructParent ID niet gevonden.
support.only.sha1.hash.algorithm=Enkel ondersteuning voor SHA1 hash algoritme.
support.only.rsa.and.dsa.algorithms=Enkel ondersteuning voor RSA en DSA algoritmes.
invalid.structparent=Ongeldige StructParent.
diff --git a/itext/src/test/java/com/itextpdf/text/pdf/BarcodeDatamatrixTest/BarcodeDatamatrixTest.java b/itext/src/test/java/com/itextpdf/text/pdf/BarcodeDatamatrixTest/BarcodeDatamatrixTest.java
new file mode 100644
index 0000000000..cd4b16939d
--- /dev/null
+++ b/itext/src/test/java/com/itextpdf/text/pdf/BarcodeDatamatrixTest/BarcodeDatamatrixTest.java
@@ -0,0 +1,345 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2017 iText Group NV
+ Authors: iText Software.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License version 3
+ as published by the Free Software Foundation with the addition of the
+ following permission added to Section 15 as permitted in Section 7(a):
+ FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
+ ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
+ OF THIRD PARTY RIGHTS
+
+ 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 http://www.gnu.org/licenses or write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA, 02110-1301 USA, or download the license from the following URL:
+ http://itextpdf.com/terms-of-use/
+
+ The interactive user interfaces in modified source and object code versions
+ of this program must display Appropriate Legal Notices, as required under
+ Section 5 of the GNU Affero General Public License.
+
+ In accordance with Section 7(b) of the GNU Affero General Public License,
+ a covered work must retain the producer line in every PDF that is created
+ or manipulated using iText.
+
+ You can be released from the requirements of the license by purchasing
+ a commercial license. Buying such a license is mandatory as soon as you
+ develop commercial activities involving the iText software without
+ disclosing the source code of your own applications.
+ These activities include: offering paid services to customers as an ASP,
+ serving PDFs on the fly in a web application, shipping iText with a closed
+ source product.
+
+ For more information, please contact iText Software Corp. at this
+ address: sales@itextpdf.com
+ */
+package com.itextpdf.text.pdf.BarcodeDatamatrixTest;
+
+import com.itextpdf.awt.geom.AffineTransform;
+import com.itextpdf.testutils.CompareTool;
+import com.itextpdf.testutils.ITextTest;
+import com.itextpdf.text.BaseColor;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.PageSize;
+import com.itextpdf.text.Paragraph;
+import com.itextpdf.text.pdf.BarcodeDatamatrix;
+import com.itextpdf.text.pdf.PdfContentByte;
+import com.itextpdf.text.pdf.PdfWriter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+
+public class BarcodeDatamatrixTest extends ITextTest {
+ public static final String sourceFolder = "./src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/";
+ public static final String destinationFolder = "./target/com/itextpdf/test/BarcodeDatamatrix/";
+
+ @Before
+ public void setUp() {
+ new File(destinationFolder).mkdirs();
+ }
+
+
+ protected void makePdf(String outPdf) throws Exception {
+
+ }
+
+ protected String getOutPdf() {
+ return null;
+ }
+
+ @Test
+ public void barcode01Test() throws IOException, DocumentException, InterruptedException {
+ String filename = "barcodeDataMatrix01.pdf";
+ String code = "AAAAAAAAAA;BBBBAAAA3;00028;BBBAA05;AAAA;AAAAAA;1234567;AQWXSZ;JEAN;;;;7894561;AQWXSZ;GEO;;;;1;1;1;1;0;0;1;0;1;0;0;0;1;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 01"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.GREEN,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+
+ @Test
+ public void barcode02Test() throws IOException, DocumentException, InterruptedException {
+ String filename = "barcodeDataMatrix02.pdf";
+ String code = "\u0434\u0438\u043C\u0430";// ????
+ String encoding = "UTF-8";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 02"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix(code, encoding);
+ barcode.placeBarcode(cb, BaseColor.GREEN,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+
+ @Test
+ public void barcode03Test() throws DocumentException, IOException, InterruptedException {
+ String filename = "barcodeDataMatrix03.pdf";
+ String code = "AbcdFFghijklmnopqrstuWXSQ";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 03"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setWidth(36);
+ barcode.setHeight(12);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.BLACK,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+
+ @Test
+ public void barcode04Test() throws DocumentException, IOException, InterruptedException{
+ String filename = "barcodeDataMatrix04.pdf";
+ String code = "01AbcdefgAbcdefg123451231231234";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 04"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setWidth(36);
+ barcode.setHeight(12);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.BLACK,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+
+ }
+
+ @Test
+ public void barcode05Test()throws DocumentException, IOException, InterruptedException {
+ String filename = "barcodeDataMatrix05.pdf";
+ String code = "aaabbbcccdddAAABBBAAABBaaabbbcccdddaaa";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 05"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setWidth(40);
+ barcode.setHeight(40);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.BLACK,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+
+
+ }
+
+ @Test
+ public void barcode06Test()throws DocumentException, IOException, InterruptedException {
+ String filename = "barcodeDataMatrix06.pdf";
+ String code = ">>>\r>>>THIS VERY TEXT>>\r>";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 06"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setWidth(36);
+ barcode.setHeight(12);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.BLACK,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+
+ @Test
+ public void barcode07Test() throws IOException, DocumentException, InterruptedException {
+ String filename = "barcodeDataMatrix07.pdf";
+ String code = "AAAAAAAAAA;BBBBAAAA3;00028;BBBAA05;AAAA;AAAAAA;1234567;AQWXSZ;JEAN;;;;7894561;AQWXSZ;GEO;;;;1;1;1;1;0;0;1;0;1;0;0;0;1;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 07"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setOptions(BarcodeDatamatrix.DM_ASCII);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.GREEN,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+
+ @Test
+ public void barcode08Test() throws IOException, DocumentException, InterruptedException {
+ String filename = "barcodeDataMatrix08.pdf";
+ String code = "AAAAAAAAAA;BBBBAAAA3;00028;BBBAA05;AAAA;AAAAAA;1234567;AQWXSZ;JEAN;;;;7894561;AQWXSZ;GEO;;;;1;1;1;1;0;0;1;0;1;0;0;0;1;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 08"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setOptions(BarcodeDatamatrix.DM_C40);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.GREEN,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+
+ @Test
+ public void barcode09Test() throws IOException, DocumentException, InterruptedException {
+ String filename = "barcodeDataMatrix09.pdf";
+ String code = "AAAAAAAAAA;BBBBAAAA3;00028;BBBAA05;AAAA;AAAAAA;1234567;AQWXSZ;JEAN;;;;7894561;AQWXSZ;GEO;;;;1;1;1;1;0;0;1;0;1;0;0;0;1;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 09"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setOptions(BarcodeDatamatrix.DM_TEXT);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.GREEN,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+
+ @Test
+ public void barcode10Test() throws IOException, DocumentException, InterruptedException {
+ String filename = "barcodeDataMatrix10.pdf";
+ String code = "AAAAAAAAAA;BBBBAAAA3;00028;BBBAA05;AAAA;AAAAAA;1234567;AQWXSZ;JEAN;;;;7894561;AQWXSZ;GEO;;;;1;1;1;1;0;0;1;0;1;0;0;0;1;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 10"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setOptions(BarcodeDatamatrix.DM_B256);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.GREEN,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+
+ @Test
+ public void barcode11Test() throws IOException, DocumentException, InterruptedException {
+ String filename = "barcodeDataMatrix11.pdf";
+ String code = "AAAAAAAAAA;BBBBAAAA3;00028;BBBAA05;AAAA;AAAAAA;1234567;AQWXSZ;JEAN;;;;7894561;AQWXSZ;GEO;;;;1;1;1;1;0;0;1;0;1;0;0;0;1;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 11"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setOptions(BarcodeDatamatrix.DM_X12);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.GREEN,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+ @Test
+ public void barcode12Test() throws IOException, DocumentException, InterruptedException {
+ String filename = "barcodeDataMatrix12.pdf";
+ String code = "AAAAAAAAAA;BBBBAAAA3;00028;BBBAA05;AAAA;AAAAAA;1234567;AQWXSZ;JEAN;;;;7894561;AQWXSZ;GEO;;;;1;1;1;1;0;0;1;0;1;0;0;0;1;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 12"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setOptions(BarcodeDatamatrix.DM_EDIFACT);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.GREEN,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+ @Test
+ public void barcode13Test() throws IOException, DocumentException, InterruptedException {
+ String filename = "barcodeDataMatrix13.pdf";
+ String code = "AAAAAAAAAA;BBBBAAAA3;00028;BBBAA05;AAAA;AAAAAA;1234567;AQWXSZ;JEAN;;;;7894561;AQWXSZ;GEO;;;;1;1;1;1;0;0;1;0;1;0;0;0;1;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
+
+ Document document = new Document(PageSize.A4);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destinationFolder + filename));
+ document.open();
+ document.add(new Paragraph("Datamatrix test 13"));
+ PdfContentByte cb = writer.getDirectContent();
+ cb.concatCTM(AffineTransform.getTranslateInstance(PageSize.A4.getWidth()/2-100,PageSize.A4.getHeight()/2-100));
+ BarcodeDatamatrix barcode = new BarcodeDatamatrix();
+ barcode.setOptions(BarcodeDatamatrix.DM_RAW);
+ barcode.generate(code);
+ barcode.placeBarcode(cb, BaseColor.GREEN,5,5);
+ document.close();
+
+ Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, sourceFolder + "cmp_" + filename, destinationFolder, "diff_"));
+ }
+}
diff --git a/itext/src/test/java/com/itextpdf/text/pdf/FlatteningTest.java b/itext/src/test/java/com/itextpdf/text/pdf/FlatteningTest.java
index 05ed7b0aa6..4b6dac9f14 100644
--- a/itext/src/test/java/com/itextpdf/text/pdf/FlatteningTest.java
+++ b/itext/src/test/java/com/itextpdf/text/pdf/FlatteningTest.java
@@ -50,6 +50,8 @@
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.events.FieldPositioningEvents;
+import junit.framework.Assert;
+import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -58,10 +60,9 @@
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
-
-import org.junit.Test;
-
-import junit.framework.Assert;
+import java.io.OutputStream;
+import java.util.Map;
+import java.util.Set;
/**
* @author Michael Demey
@@ -71,6 +72,38 @@ public class FlatteningTest {
private static final String RESOURCES_FOLDER = "./src/test/resources/com/itextpdf/text/pdf/FlatteningTest/";
private static final String OUTPUT_FOLDER = "./target/com/itextpdf/test/pdf/FlatteningTest/";
+ @Test
+ public void testFlatteningNewAppearances() throws InterruptedException, DocumentException, IOException {
+ new File(OUTPUT_FOLDER).mkdirs();
+
+ final String OUT = "tpl3_flattened.pdf";
+
+ PdfReader reader = new PdfReader(RESOURCES_FOLDER + "tpl3.pdf");
+ AcroFields fields = reader.getAcroFields();
+ if (fields != null && fields.getFields() != null && fields.getFields().size() > 0) {
+ OutputStream out = null;
+ out = new FileOutputStream(OUTPUT_FOLDER + OUT);
+ PdfStamper stamp = new PdfStamper(reader, out);
+ stamp.setFormFlattening(true);
+ AcroFields form = stamp.getAcroFields();
+
+ Set> map = form.getFields().entrySet();
+ for (Map.Entry e : map) {
+ form.setField(e.getKey(), e.getKey());
+ }
+
+ stamp.close();
+ out.close();
+ }
+ reader.close();
+
+ CompareTool compareTool = new CompareTool();
+ String errorMessage = compareTool.compare(OUTPUT_FOLDER + OUT, RESOURCES_FOLDER + "cmp_" + OUT, OUTPUT_FOLDER, "diff");
+ if (errorMessage != null) {
+ Assert.fail(errorMessage);
+ }
+ }
+
@Test
public void testFlattening() throws IOException, DocumentException, InterruptedException {
final String INPUT_FOLDER = RESOURCES_FOLDER + "input/";
@@ -322,4 +355,27 @@ public void testAnnotationFlatteningWithSkewAndRotation() throws IOException, Do
Assert.fail(errorMessage);
}
}
+
+ @Test
+ public void testRotatedFilledField() throws IOException, DocumentException, InterruptedException {
+ new File(OUTPUT_FOLDER).mkdirs();
+
+ String file = "rotatedField.pdf";
+ PdfReader pdfReader = new PdfReader(RESOURCES_FOLDER + file);
+ PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(OUTPUT_FOLDER + file));
+
+ AcroFields fields = pdfStamper.getAcroFields();
+ fields.setField("Text1", "TEST");
+ fields.setGenerateAppearances(true);
+
+ pdfStamper.setFormFlattening(true);
+ pdfStamper.close();
+ pdfReader.close();
+ // compare
+ CompareTool compareTool = new CompareTool();
+ String errorMessage = compareTool.compareByContent(OUTPUT_FOLDER + file, RESOURCES_FOLDER + "cmp_" + file, OUTPUT_FOLDER, "diff");
+ if (errorMessage != null) {
+ Assert.fail(errorMessage);
+ }
+ }
}
diff --git a/itext/src/test/java/com/itextpdf/text/pdf/FreeTextFlatteningTest.java b/itext/src/test/java/com/itextpdf/text/pdf/FreeTextFlatteningTest.java
new file mode 100644
index 0000000000..9596687bd5
--- /dev/null
+++ b/itext/src/test/java/com/itextpdf/text/pdf/FreeTextFlatteningTest.java
@@ -0,0 +1,198 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2017 iText Group NV
+ Authors: iText Software.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License version 3
+ as published by the Free Software Foundation with the addition of the
+ following permission added to Section 15 as permitted in Section 7(a):
+ FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
+ ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
+ OF THIRD PARTY RIGHTS
+
+ 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 http://www.gnu.org/licenses or write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA, 02110-1301 USA, or download the license from the following URL:
+ http://itextpdf.com/terms-of-use/
+
+ The interactive user interfaces in modified source and object code versions
+ of this program must display Appropriate Legal Notices, as required under
+ Section 5 of the GNU Affero General Public License.
+
+ In accordance with Section 7(b) of the GNU Affero General Public License,
+ a covered work must retain the producer line in every PDF that is created
+ or manipulated using iText.
+
+ You can be released from the requirements of the license by purchasing
+ a commercial license. Buying such a license is mandatory as soon as you
+ develop commercial activities involving the iText software without
+ disclosing the source code of your own applications.
+ These activities include: offering paid services to customers as an ASP,
+ serving PDFs on the fly in a web application, shipping iText with a closed
+ source product.
+
+ For more information, please contact iText Software Corp. at this
+ address: sales@itextpdf.com
+ */
+package com.itextpdf.text.pdf;
+
+import com.itextpdf.testutils.CompareTool;
+import com.itextpdf.text.DocumentException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.itextpdf.text.pdf.parser.ContentByteUtils;
+import com.itextpdf.text.pdf.parser.ImageRenderInfo;
+import com.itextpdf.text.pdf.parser.PdfContentStreamProcessor;
+import com.itextpdf.text.pdf.parser.RenderListener;
+import com.itextpdf.text.pdf.parser.TextRenderInfo;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class FreeTextFlatteningTest {
+
+ private final static String FOLDER = "./src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/";
+ private final static String TARGET = "./target/com/itextpdf/test/pdf/FreeTextFlattening/";
+
+ @BeforeClass
+ public static void setUp() {
+ new File(TARGET).mkdirs();
+ }
+
+ @Test
+ public void flattenCorrectlyTest() throws IOException, DocumentException, InterruptedException {
+ String outputFile = TARGET + "freetext-flattened.pdf";
+
+ flattenFreeText(FOLDER + "freetext.pdf", outputFile);
+ checkAnnotationSize(outputFile, 0);
+
+ String errorMessage = new CompareTool().compareByContent(outputFile, FOLDER + "flattened.pdf", TARGET, "diff");
+ if ( errorMessage != null ) {
+ Assert.fail(errorMessage);
+ }
+ }
+
+ @Test
+ public void checkPageContentTest() throws IOException, DocumentException, InterruptedException {
+ checkPageContent(FOLDER + "flattened.pdf");
+ }
+
+ @Test
+ public void flattenWithoutDA() throws IOException, DocumentException {
+ String outputFile = TARGET + "freetext-flattened-no-da.pdf";
+
+ flattenFreeText(FOLDER + "freetext-no-da.pdf", outputFile);
+ checkAnnotationSize(outputFile, 1);
+ }
+
+ @Test
+ public void flattenAndCheckCourier() throws IOException, DocumentException, InterruptedException {
+ String inputFile = FOLDER + "freetext-courier.pdf";
+ String outputFile = TARGET + "freetext-courier-flattened.pdf";
+
+ flattenFreeText(inputFile, outputFile);
+ checkPageContent(outputFile);
+ }
+
+ @Test
+ public void flattenAndCheckShortFontName() throws IOException, DocumentException, InterruptedException {
+ String inputFile = FOLDER + "freetext-times-short.pdf";
+ String outputFile = TARGET + "freetext-times-short-flattened.pdf";
+
+ flattenFreeText(inputFile, outputFile);
+ checkPageContent(outputFile);
+
+ String errorMessage = new CompareTool().compareByContent(outputFile, FOLDER + "cmp_freetext-times-short-flattened.pdf", TARGET, "diff_short");
+ if ( errorMessage != null ) {
+ Assert.fail(errorMessage);
+ }
+ }
+
+ private void checkAnnotationSize(String path, int expectedAnnotationsSize) throws IOException, DocumentException {
+ FileInputStream fin = null;
+ try {
+ fin = new FileInputStream(path);
+ checkAnnotationSize(fin, expectedAnnotationsSize);
+ } finally {
+ if (fin != null) {
+ fin.close();
+ }
+ }
+ }
+
+ private void checkAnnotationSize(InputStream inputStream, int expectedAnnotationsSize) throws IOException, DocumentException {
+ PdfReader reader = new PdfReader(inputStream);
+ PdfDictionary pageDictionary = reader.getPageN(1);
+ if ( pageDictionary.contains(PdfName.ANNOTS )) {
+ PdfArray annotations = pageDictionary.getAsArray(PdfName.ANNOTS);
+ Assert.assertTrue(annotations.size() == expectedAnnotationsSize);
+ }
+ }
+
+ private void flattenFreeText(String inputPath, String outputPath) throws IOException, DocumentException {
+ FileInputStream fin = null;
+ FileOutputStream fout = null;
+ try {
+ fin = new FileInputStream(inputPath);
+ fout = new FileOutputStream(outputPath);
+ flattenFreeText(fin, fout);
+ } finally {
+ if (fin != null) {
+ fin.close();
+ }
+ if (fout != null) {
+ fout.close();
+ }
+ }
+ }
+
+ private void flattenFreeText(final InputStream inputStream, OutputStream outputStream) throws IOException, DocumentException {
+ PdfReader reader = new PdfReader(inputStream);
+ PdfStamper stamper = new PdfStamper(reader, outputStream);
+
+ stamper.setFormFlattening(true);
+ stamper.setFreeTextFlattening(true);
+ stamper.setAnnotationFlattening(true);
+
+ stamper.close();
+ }
+
+ private void checkPageContent(String path) throws IOException, DocumentException {
+ PdfReader pdfReader = new PdfReader(path);
+ try {
+ PdfDictionary pageDic = pdfReader.getPageN(1);
+
+ RenderListener dummy = new RenderListener() {
+ public void beginTextBlock() {
+ }
+
+ public void renderText(TextRenderInfo renderInfo) {
+ }
+
+ public void endTextBlock() {
+ }
+
+ public void renderImage(ImageRenderInfo renderInfo) {
+ }
+ };
+ PdfContentStreamProcessor processor = new PdfContentStreamProcessor(dummy);
+
+ PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
+ processor.processContent(ContentByteUtils.getContentBytesForPage(pdfReader, 1), resourcesDic);
+ } finally {
+ pdfReader.close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/itext/src/test/java/com/itextpdf/text/pdf/PdfCopyTest.java b/itext/src/test/java/com/itextpdf/text/pdf/PdfCopyTest.java
index 5208f9fc51..aa3409d7a6 100644
--- a/itext/src/test/java/com/itextpdf/text/pdf/PdfCopyTest.java
+++ b/itext/src/test/java/com/itextpdf/text/pdf/PdfCopyTest.java
@@ -79,6 +79,7 @@ public class PdfCopyTest {
@Before
public void setUp() throws Exception {
TestResourceUtils.purgeTempFiles();
+ new File("./target/com/itextpdf/test/pdf/PdfCopyTest").mkdirs();
}
@After
diff --git a/itext/src/test/java/com/itextpdf/text/pdf/PdfDictionaryTest.java b/itext/src/test/java/com/itextpdf/text/pdf/PdfDictionaryTest.java
new file mode 100644
index 0000000000..5c00ed4a98
--- /dev/null
+++ b/itext/src/test/java/com/itextpdf/text/pdf/PdfDictionaryTest.java
@@ -0,0 +1,97 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2017 iText Group NV
+ Authors: iText Software.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License version 3
+ as published by the Free Software Foundation with the addition of the
+ following permission added to Section 15 as permitted in Section 7(a):
+ FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
+ ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
+ OF THIRD PARTY RIGHTS
+
+ 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 http://www.gnu.org/licenses or write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA, 02110-1301 USA, or download the license from the following URL:
+ http://itextpdf.com/terms-of-use/
+
+ The interactive user interfaces in modified source and object code versions
+ of this program must display Appropriate Legal Notices, as required under
+ Section 5 of the GNU Affero General Public License.
+
+ In accordance with Section 7(b) of the GNU Affero General Public License,
+ a covered work must retain the producer line in every PDF that is created
+ or manipulated using iText.
+
+ You can be released from the requirements of the license by purchasing
+ a commercial license. Buying such a license is mandatory as soon as you
+ develop commercial activities involving the iText software without
+ disclosing the source code of your own applications.
+ These activities include: offering paid services to customers as an ASP,
+ serving PDFs on the fly in a web application, shipping iText with a closed
+ source product.
+
+ For more information, please contact iText Software Corp. at this
+ address: sales@itextpdf.com
+ */
+package com.itextpdf.text.pdf;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PdfDictionaryTest {
+ @Test
+ public void pdfDictionaryGetReturnsNullIfKeyIsNull() {
+ PdfDictionary dictionary = new PdfDictionary();
+
+ PdfObject value = dictionary.get(null);
+
+ Assert.assertNull(value);
+ }
+
+ @Test
+ public void pdfDictionaryContainsReturnsFalseIfKeyIsNull() {
+ PdfDictionary dictionary = new PdfDictionary();
+
+ boolean contained = dictionary.contains(null);
+
+ Assert.assertFalse(contained);
+ }
+
+ @Test
+ public void pdfDictionaryRemoveDoesNothingIfKeyIsNull() {
+ PdfDictionary dictionary = new PdfDictionary();
+
+ dictionary.remove(null);
+ }
+
+ @Test
+ public void pdfDictionaryPutThrowsExceptionIfKeyIsNull() {
+ PdfDictionary dictionary = new PdfDictionary();
+
+ try {
+ dictionary.put(null, new PdfName("null"));
+ Assert.fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ Assert.assertEquals(e.getMessage(), "key is null.");
+ }
+ }
+
+ @Test
+ public void pdfDictionaryPutExThrowsExceptionIfKeyIsNull() {
+ PdfDictionary dictionary = new PdfDictionary();
+
+ try {
+ dictionary.putEx(null, new PdfName("null"));
+ Assert.fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ Assert.assertEquals(e.getMessage(), "key is null.");
+ }
+ }
+}
diff --git a/itext/src/test/java/com/itextpdf/text/pdf/PdfEncryptionTest.java b/itext/src/test/java/com/itextpdf/text/pdf/PdfEncryptionTest.java
index 89f1c0c858..e520f3c67a 100644
--- a/itext/src/test/java/com/itextpdf/text/pdf/PdfEncryptionTest.java
+++ b/itext/src/test/java/com/itextpdf/text/pdf/PdfEncryptionTest.java
@@ -46,16 +46,35 @@ This file is part of the iText (R) project.
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
+import com.itextpdf.text.pdf.security.BouncyCastleDigest;
+import com.itextpdf.text.pdf.security.DigestAlgorithms;
+import com.itextpdf.text.pdf.security.ExternalDigest;
+import com.itextpdf.text.pdf.security.ExternalSignature;
+import com.itextpdf.text.pdf.security.MakeSignature;
+import com.itextpdf.text.pdf.security.PrivateKeySignature;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.Before;
+import org.junit.Test;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
-import org.junit.Before;
-import org.junit.Test;
-
-import junit.framework.Assert;
-
-import static junit.framework.Assert.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import static junit.framework.Assert.assertNull;
public class PdfEncryptionTest {
@@ -119,4 +138,117 @@ public void computeUserPasswordAES256() throws Exception {
assertNull(password);
}
+
+ @Test
+ public void encryptWithCertificateAndSignTest() throws IOException, DocumentException, GeneralSecurityException {
+ removeCryptographyRestrictions();
+ Security.addProvider(new BouncyCastleProvider());
+ String inPdf = SOURCE_FOLDER + "in.pdf";
+ String outPdf = DEST_FOLDER + "encrypt_cert_signed.pdf";
+ String tmpPdf = DEST_FOLDER + "encrypt_cert.pdf";
+
+ encryptPdfWithCertificate(inPdf, tmpPdf, SOURCE_FOLDER + "test.cer");
+
+ Certificate cert = getPublicCertificate(SOURCE_FOLDER + "test.cer");
+ PrivateKey privateKey = getPrivateKey(SOURCE_FOLDER + "test.p12");
+ certSign(getPublicCertificate(SOURCE_FOLDER + "test.cer"), privateKey, outPdf, new PdfReader(tmpPdf, cert, privateKey, new BouncyCastleProvider().getName()), "reason", "location");
+ restoreCryptographyRestrictions();
+ }
+
+ private static void encryptPdfWithCertificate(String sourceDocument, String targetDocument, String certPath) throws IOException, DocumentException, CertificateException {
+ Certificate cert = getPublicCertificate(certPath);
+ Certificate[] certs = new Certificate[] {cert};
+ PdfReader reader = new PdfReader(sourceDocument);
+ PdfStamper st = new PdfStamper(reader, new FileOutputStream(targetDocument), '\0', false);
+ int[] x = new int[1];
+ x[0] = PdfWriter.ALLOW_SCREENREADERS;
+ st.setEncryption(certs, x, PdfWriter.STANDARD_ENCRYPTION_40);
+ st.close();
+ }
+
+ private static Certificate getPublicCertificate(String path) throws IOException, CertificateException {
+ FileInputStream is = new FileInputStream(path);
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
+ return cert;
+ }
+
+ private static PrivateKey getPrivateKey(String path) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
+ KeyStore ks = KeyStore.getInstance("PKCS12");
+ ks.load(new FileInputStream(path), "kspass".toCharArray());
+ String alias = ks.aliases().nextElement();
+ PrivateKey pk = (PrivateKey) ks.getKey(alias, "kspass".toCharArray());
+ return pk;
+ }
+
+ private static void certSign(Certificate cert, PrivateKey privateKey, String destinationPath, PdfReader reader, String reason, String location) throws IOException, DocumentException, GeneralSecurityException {
+ Certificate[] chain = new Certificate[] {cert};
+
+ BouncyCastleProvider provider = new BouncyCastleProvider();
+ ExternalSignature pks = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA1, provider.getName());
+
+ FileOutputStream fout = new FileOutputStream(destinationPath);
+ PdfStamper stamper = PdfStamper.createSignature(reader, fout, '\0', null, true);
+ PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
+ appearance.setReason(reason);
+ appearance.setLocation(location);
+ ExternalDigest digest = new BouncyCastleDigest();
+ MakeSignature.signDetached(appearance, digest, pks, chain, null, null, null, 0,
+ MakeSignature.CryptoStandard.CADES);
+ stamper.close();
+ }
+
+ /**
+ * Due to import control restrictions by the governments of a few countries,
+ * the encryption libraries shipped by default with the Java SDK restrict the
+ * length, and as a result the strength, of encryption keys. Be aware that by
+ * using this method we remove cryptography restrictions via reflection for
+ * testing purposes.
+ *
+ * For more conventional way of solving this problem you need to replace the
+ * default security JARs in your Java installation with the Java Cryptography
+ * Extension (JCE) Unlimited Strength Jurisdiction Policy Files. These JARs
+ * are available for download from http://java.oracle.com/ in eligible countries.
+ */
+ public static void removeCryptographyRestrictions() {
+ try {
+ Field field = Class.forName("javax.crypto.JceSecurity").
+ getDeclaredField("isRestricted");
+ if (field.isAccessible()) {
+ // unexpected case
+ return;
+ }
+
+ Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+ modifiersField.setAccessible(false);
+
+ field.setAccessible(true);
+ if (field.getBoolean(null)) {
+ field.set(null, java.lang.Boolean.FALSE);
+ } else {
+ field.setAccessible(false);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * By using this method we restore cryptography restrictions via reflection.
+ */
+ public static void restoreCryptographyRestrictions() {
+ try {
+ Field field = Class.forName("javax.crypto.JceSecurity").
+ getDeclaredField("isRestricted");
+ if (field.isAccessible()) {
+ field.set(null, java.lang.Boolean.TRUE);
+ field.setAccessible(false);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
}
diff --git a/itext/src/test/java/com/itextpdf/text/pdf/languages/IndicCompositeCharacterComparatorTest.java b/itext/src/test/java/com/itextpdf/text/pdf/languages/IndicCompositeCharacterComparatorTest.java
new file mode 100644
index 0000000000..3077a668f7
--- /dev/null
+++ b/itext/src/test/java/com/itextpdf/text/pdf/languages/IndicCompositeCharacterComparatorTest.java
@@ -0,0 +1,83 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2017 iText Group NV
+ Authors: iText Software.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License version 3
+ as published by the Free Software Foundation with the addition of the
+ following permission added to Section 15 as permitted in Section 7(a):
+ FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
+ ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
+ OF THIRD PARTY RIGHTS
+
+ 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 http://www.gnu.org/licenses or write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA, 02110-1301 USA, or download the license from the following URL:
+ http://itextpdf.com/terms-of-use/
+
+ The interactive user interfaces in modified source and object code versions
+ of this program must display Appropriate Legal Notices, as required under
+ Section 5 of the GNU Affero General Public License.
+
+ In accordance with Section 7(b) of the GNU Affero General Public License,
+ a covered work must retain the producer line in every PDF that is created
+ or manipulated using iText.
+
+ You can be released from the requirements of the license by purchasing
+ a commercial license. Buying such a license is mandatory as soon as you
+ develop commercial activities involving the iText software without
+ disclosing the source code of your own applications.
+ These activities include: offering paid services to customers as an ASP,
+ serving PDFs on the fly in a web application, shipping iText with a closed
+ source product.
+
+ For more information, please contact iText Software Corp. at this
+ address: sales@itextpdf.com
+ */
+package com.itextpdf.text.pdf.languages;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class IndicCompositeCharacterComparatorTest {
+
+ @Test
+ public void testLengthIsEqualAndStringsAreEqual() {
+ String oneString = "\u0938\u0924";
+ String twoString = "\u0938\u0924";
+ int result = new IndicCompositeCharacterComparator().compare(oneString, twoString);
+ assertTrue("expected to be equal", result == 0);
+ }
+
+ @Test
+ public void testLengthIsEqualAndStringsAreNotEqual() {
+ String oneString = "\u0938\u0924";
+ String twoString = "\u0924\u0938";
+ int result = new IndicCompositeCharacterComparator().compare(oneString, twoString);
+ assertTrue("expected not to be equal", result != 0);
+ }
+
+ @Test
+ public void testFirstStringIsShorter() {
+ String oneString = "\u0938\u0924";
+ String twoString = "\u0938\u0924\u0938\u0924";
+ int result = new IndicCompositeCharacterComparator().compare(oneString, twoString);
+ assertTrue("expected to be greater than", result >= 1);
+ }
+
+ @Test
+ public void testFirstStringIsLonger() {
+ String oneString = "\u0938\u0924\u0938\u0924";
+ String twoString = "\u0938\u0924";
+ int result = new IndicCompositeCharacterComparator().compare(oneString, twoString);
+ assertTrue("expected to be less than", result <= -1);
+ }
+
+}
\ No newline at end of file
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix01.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix01.pdf
new file mode 100644
index 0000000000..21e96f9f9b
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix01.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix02.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix02.pdf
new file mode 100644
index 0000000000..760f56e6d6
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix02.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix03.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix03.pdf
new file mode 100644
index 0000000000..8e5ad2c9a9
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix03.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix04.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix04.pdf
new file mode 100644
index 0000000000..dea77eb0a2
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix04.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix05.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix05.pdf
new file mode 100644
index 0000000000..8e6a842b99
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix05.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix06.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix06.pdf
new file mode 100644
index 0000000000..a90273e68e
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix06.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix07.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix07.pdf
new file mode 100644
index 0000000000..42806bb1cf
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix07.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix08.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix08.pdf
new file mode 100644
index 0000000000..dace7b8a69
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix08.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix09.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix09.pdf
new file mode 100644
index 0000000000..327d5f4485
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix09.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix10.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix10.pdf
new file mode 100644
index 0000000000..4940fc0ed7
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix10.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix11.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix11.pdf
new file mode 100644
index 0000000000..917f3d483b
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix11.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix12.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix12.pdf
new file mode 100644
index 0000000000..5113a3910f
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix12.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix13.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix13.pdf
new file mode 100644
index 0000000000..74a8c4e59d
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/BarcodeDatamatrix/cmp_barcodeDataMatrix13.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/cmp_rotatedField.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/cmp_rotatedField.pdf
new file mode 100644
index 0000000000..2ca54188af
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/cmp_rotatedField.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/cmp_tpl3_flattened.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/cmp_tpl3_flattened.pdf
new file mode 100644
index 0000000000..0b680e7d67
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/cmp_tpl3_flattened.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/rotatedField.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/rotatedField.pdf
new file mode 100644
index 0000000000..6c9b469faf
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/rotatedField.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/tpl3.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/tpl3.pdf
new file mode 100644
index 0000000000..18bfb24421
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FlatteningTest/tpl3.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/cmp_freetext-times-short-flattened.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/cmp_freetext-times-short-flattened.pdf
new file mode 100644
index 0000000000..de5a4c423d
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/cmp_freetext-times-short-flattened.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/flattened.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/flattened.pdf
new file mode 100644
index 0000000000..18db54b3be
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/flattened.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext-courier.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext-courier.pdf
new file mode 100644
index 0000000000..b6e6ffd975
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext-courier.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext-no-da.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext-no-da.pdf
new file mode 100644
index 0000000000..1305a4bcc2
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext-no-da.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext-times-short.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext-times-short.pdf
new file mode 100644
index 0000000000..3c03454c1f
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext-times-short.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext.pdf
new file mode 100644
index 0000000000..36faaf32fa
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/FreeTextFlatteningTest/freetext.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/PdfEncryptionTest/in.pdf b/itext/src/test/resources/com/itextpdf/text/pdf/PdfEncryptionTest/in.pdf
new file mode 100644
index 0000000000..2f59b49e6a
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/PdfEncryptionTest/in.pdf differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/PdfEncryptionTest/test.cer b/itext/src/test/resources/com/itextpdf/text/pdf/PdfEncryptionTest/test.cer
new file mode 100644
index 0000000000..fbaad2b382
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/PdfEncryptionTest/test.cer differ
diff --git a/itext/src/test/resources/com/itextpdf/text/pdf/PdfEncryptionTest/test.p12 b/itext/src/test/resources/com/itextpdf/text/pdf/PdfEncryptionTest/test.p12
new file mode 100644
index 0000000000..dc8d373503
Binary files /dev/null and b/itext/src/test/resources/com/itextpdf/text/pdf/PdfEncryptionTest/test.p12 differ
diff --git a/pdfa/pom.xml b/pdfa/pom.xml
index c4f96d0d32..ff94b47c02 100644
--- a/pdfa/pom.xml
+++ b/pdfa/pom.xml
@@ -10,7 +10,7 @@
itext-pdfa
- 5.5.11
+ 5.5.12iText PDF/AiText ISO-19005 Module
@@ -144,18 +144,6 @@
http://developers.itextpdf.com/reference/classes
-
diff --git a/pdfa/src/main/java/com/itextpdf/text/zugferd/InvoiceDOM.java b/pdfa/src/main/java/com/itextpdf/text/zugferd/InvoiceDOM.java
index e727bb0163..4e452e8121 100644
--- a/pdfa/src/main/java/com/itextpdf/text/zugferd/InvoiceDOM.java
+++ b/pdfa/src/main/java/com/itextpdf/text/zugferd/InvoiceDOM.java
@@ -64,8 +64,10 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.StringReader;
import java.util.Date;
+import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -82,6 +84,8 @@
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
@@ -121,8 +125,9 @@ public InvoiceDOM(BasicProfile data)
// loading the XML template
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ docBuilder.setEntityResolver(new SafeEmptyEntityResolver());
InputStream is = StreamUtil.getResourceStream("com/itextpdf/text/zugferd/zugferd-template.xml");
- doc = docBuilder.parse(is);
+ doc = docBuilder.parse(is);
// importing the data
importData(doc, data);
}
@@ -1161,11 +1166,14 @@ protected void importLineItemBasic(Element parent,
public byte[] toXML() throws TransformerException {
removeEmptyNodes(doc);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ try {
+ transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ } catch (Exception exc) {}
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
- DOMSource source = new DOMSource(doc);
+ DOMSource source = new DOMSource(doc);
ByteArrayOutputStream out = new ByteArrayOutputStream();
Result result = new StreamResult(out);
transformer.transform(source, result);
@@ -1203,4 +1211,10 @@ protected void check(String s, String message) throws DataIncompleteException {
if (s == null || s.trim().length() == 0)
throw new DataIncompleteException(message);
}
+
+ private static class SafeEmptyEntityResolver implements EntityResolver {
+ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
+ return new InputSource(new StringReader(""));
+ }
+ }
}
diff --git a/pdfa/src/test/resources/com/itextpdf/text/pdf/cidset/cmp_cidFontCheckTest3.pdf b/pdfa/src/test/resources/com/itextpdf/text/pdf/cidset/cmp_cidFontCheckTest3.pdf
index 5a6ed82127..12a1e8aa6f 100644
Binary files a/pdfa/src/test/resources/com/itextpdf/text/pdf/cidset/cmp_cidFontCheckTest3.pdf and b/pdfa/src/test/resources/com/itextpdf/text/pdf/cidset/cmp_cidFontCheckTest3.pdf differ
diff --git a/pom.xml b/pom.xml
index b64acf756d..50a62d271e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
root
- 5.5.11
+ 5.5.12pomiText
@@ -52,18 +52,6 @@
com.itextpdf.tool.xml*
-
diff --git a/xmlworker/pom.xml b/xmlworker/pom.xml
index 80945915ee..17f860e374 100644
--- a/xmlworker/pom.xml
+++ b/xmlworker/pom.xml
@@ -11,7 +11,7 @@
com.itextpdf.toolxmlworker
- 5.5.11
+ 5.5.12iText XML WorkerParses XML to PDF, with CSS support, using iText
@@ -212,18 +212,6 @@
http://developers.itextpdf.com/reference/classes
-
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/html/head/Link.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/html/head/Link.java
index 4dadb809fa..da3534a507 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/html/head/Link.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/html/head/Link.java
@@ -47,6 +47,7 @@
import java.util.List;
import com.itextpdf.text.Element;
+import com.itextpdf.text.log.Level;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.tool.xml.NoCustomContextException;
@@ -78,9 +79,13 @@ public List start(final WorkerContext ctx, final Tag tag) {
try {
getCSSResolver(ctx).addCssFile(href, false);
} catch (CssResolverException e) {
- LOG.error(String.format(LocaleMessages.getInstance().getMessage(LocaleMessages.LINK_404), href), e);
+ if (LOG.isLogging(Level.ERROR)) {
+ LOG.error(String.format(LocaleMessages.getInstance().getMessage(LocaleMessages.LINK_404), href), e);
+ }
} catch (NoCustomContextException e) {
- LOG.warn(String.format(LocaleMessages.getInstance().getMessage(LocaleMessages.CUSTOMCONTEXT_404_CONTINUE), CssResolverPipeline.class.getName()));
+ if (LOG.isLogging(Level.WARN)) {
+ LOG.warn(String.format(LocaleMessages.getInstance().getMessage(LocaleMessages.CUSTOMCONTEXT_404_CONTINUE), CssResolverPipeline.class.getName()));
+ }
}
}
}
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/html/head/Style.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/html/head/Style.java
index 4ddedadf64..fbaf0dcf37 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/html/head/Style.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/html/head/Style.java
@@ -88,7 +88,9 @@ public List content(final WorkerContext ctx, final Tag tag, final Strin
LOG.trace(content);
}
} catch (NoCustomContextException e) {
- LOG.warn(String.format(LocaleMessages.getInstance().getMessage(LocaleMessages.CUSTOMCONTEXT_404_CONTINUE), CssResolverPipeline.class.getName()));
+ if (LOG.isLogging(Level.WARN)) {
+ LOG.warn(String.format(LocaleMessages.getInstance().getMessage(LocaleMessages.CUSTOMCONTEXT_404_CONTINUE), CssResolverPipeline.class.getName()));
+ }
}
return new ArrayList(0);
}
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/StateController.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/StateController.java
index d554306460..14e50d8485 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/StateController.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/StateController.java
@@ -272,4 +272,8 @@ public XMLParser starComment() {
public XMLParser closeStarComment() {
return setState(this.closeStarComment);
}
+
+ public State getPreviousState() {
+ return previousState;
+ }
}
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/XMLParser.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/XMLParser.java
index a845420a4f..1a06d99fd0 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/XMLParser.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/XMLParser.java
@@ -41,6 +41,12 @@
*/
package com.itextpdf.tool.xml.parser;
+import com.itextpdf.text.xml.XMLUtil;
+import com.itextpdf.text.xml.simpleparser.IanaEncodings;
+import com.itextpdf.tool.xml.parser.io.EncodingUtil;
+import com.itextpdf.tool.xml.parser.io.MonitorInputReader;
+import com.itextpdf.tool.xml.parser.io.ParserMonitor;
+
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -50,14 +56,9 @@
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
-import com.itextpdf.text.xml.XMLUtil;
-import com.itextpdf.text.xml.simpleparser.IanaEncodings;
-import com.itextpdf.tool.xml.parser.io.EncodingUtil;
-import com.itextpdf.tool.xml.parser.io.MonitorInputReader;
-import com.itextpdf.tool.xml.parser.io.ParserMonitor;
-
/**
* Reads an XML file. Attach a {@link XMLParserListener} for receiving events.
*
@@ -73,6 +74,7 @@ public class XMLParser {
private String text = null;
private TagState tagState;
private Charset charset;
+ private boolean decodeSpecialChars = true;
/**
* Constructs a default XMLParser ready for HTML/XHTML processing.
@@ -217,7 +219,7 @@ public void parse(final Reader reader) throws IOException {
/**
* The actual parse method
*
- * @param r
+ * @param reader
* @throws IOException
*/
private void parseWithReader(final Reader reader) throws IOException {
@@ -366,9 +368,14 @@ public XMLParserMemory memory() {
*/
public void startElement() {
currentTagState(TagState.OPEN);
+ String tagName = this.memory.getCurrentTag();
+ Map attributes = this.memory.getAttributes();
+ if (tagName.startsWith("?")) {
+ memory().processingInstruction().setLength(0);
+ }
callText();
for (XMLParserListener l : listeners) {
- l.startElement(this.memory.getCurrentTag(), this.memory.getAttributes(), this.memory.getNameSpace());
+ l.startElement(tagName, attributes, this.memory.getNameSpace());
}
this.memory().flushNameSpace();
}
@@ -463,6 +470,18 @@ public void setMonitor(final ParserMonitor monitor) {
this.monitor = monitor;
}
+ /**
+ * Determines whether special chars like > will be decoded
+ * @param decodeSpecialChars true to decode, false to not decode
+ */
+ public void setDecodeSpecialChars(boolean decodeSpecialChars) {
+ this.decodeSpecialChars = decodeSpecialChars;
+ }
+
+ public boolean isDecodeSpecialChars() {
+ return decodeSpecialChars;
+ }
+
/**
* @return the current buffer as a String
*/
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/XMLParserMemory.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/XMLParserMemory.java
index d0667567c3..ff7a15b62a 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/XMLParserMemory.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/XMLParserMemory.java
@@ -45,7 +45,6 @@
import com.itextpdf.tool.xml.parser.state.InsideTagHTMLState;
-import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -62,6 +61,7 @@ public class XMLParserMemory {
private final StringBuilder currentEntity = new StringBuilder();
private final StringBuilder comment = new StringBuilder();
private final StringBuilder baos = new StringBuilder();
+ private final StringBuilder processingInstruction = new StringBuilder();
private final Map attr;
private String wsTag = "";
private String currentNameSpace = "";
@@ -102,6 +102,7 @@ public void currentAttr(final String attr) {
public boolean hasCurrentAttribute() {
return null != this.currentAttr;
}
+
/**
* Sets the current attribute value and adds the attribute (if it's not
* null) to the attribute map.
@@ -161,6 +162,14 @@ public StringBuilder comment() {
return this.comment;
}
+ /**
+ * Returns the xml processing instruction buffer
+ * @return processing instruction buffer
+ */
+ public StringBuilder processingInstruction() {
+ return this.processingInstruction;
+ }
+
/**
* Returns last tag that needs to be taken into account for HTML Whitespace handling.
* Used by {@link InsideTagHTMLState}, only for HTML processing.
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/InsideTagHTMLState.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/InsideTagHTMLState.java
index c1978f6652..3b96bae850 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/InsideTagHTMLState.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/InsideTagHTMLState.java
@@ -100,7 +100,7 @@ public void process(final char character) {
} else if (character == '&') {
this.parser.selectState().specialChar();
} else {
- if (character == '*' && this.parser.memory().lastChar() == '/') {
+ if (HTML.Tag.STYLE.equals(this.parser.currentTag()) && character == '*' && this.parser.memory().lastChar() == '/' && parser.memory().current().length() > 0) {
this.parser.selectState().starComment();
this.parser.memory().current().deleteCharAt(this.parser.memory().current().lastIndexOf("/"));
if (this.parser.bufferSize() > 0) {
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/ProcessingInstructionEncounteredState.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/ProcessingInstructionEncounteredState.java
index 0c4629c7d7..35839c6307 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/ProcessingInstructionEncounteredState.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/ProcessingInstructionEncounteredState.java
@@ -64,6 +64,7 @@ public ProcessingInstructionEncounteredState(final XMLParser parser) {
*/
public void process(final char character) {
String tag = this.parser.bufferToString();
+ this.parser.memory().processingInstruction().append(character);
if (name == null && Character.isWhitespace(character)) {
if (Character.isWhitespace(character)) {
name = tag;
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/SelfClosingTagState.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/SelfClosingTagState.java
index 2c80c34b48..ee357b0722 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/SelfClosingTagState.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/SelfClosingTagState.java
@@ -72,6 +72,8 @@ public void process(final char character) {
this.parser.flush();
this.parser.memory().flushNameSpace();
this.parser.selectState().inTag();
+ } else if (this.parser.selectState().getPreviousState() instanceof ProcessingInstructionEncounteredState) {
+ this.parser.memory().processingInstruction().append(character);
}
}
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/SpecialCharState.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/SpecialCharState.java
index 3b9a287117..8773d0d35c 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/SpecialCharState.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/parser/state/SpecialCharState.java
@@ -59,7 +59,7 @@ public class SpecialCharState implements State {
* @param parser the XMLParser
*/
public SpecialCharState(final XMLParser parser) {
- this.parser =parser;
+ this.parser = parser;
}
/* (non-Javadoc)
@@ -71,7 +71,7 @@ public void process(final char character) {
// if ("nbsp".equals(entity.toString())) {
// parser.append(' '); // TODO check yes or no if it's good idea to transform   into a space ?
// } else {
- char decoded = EntitiesToUnicode.decodeEntity(entity.toString());
+ char decoded = parser.isDecodeSpecialChars() ? EntitiesToUnicode.decodeEntity(entity.toString()) : 0;
if (decoded == '\0') {
parser.append('&').append(entity.toString()).append(';');
parser.memory().lastChar(';');
diff --git a/xmlworker/src/main/java/com/itextpdf/tool/xml/pipeline/end/PdfWriterPipeline.java b/xmlworker/src/main/java/com/itextpdf/tool/xml/pipeline/end/PdfWriterPipeline.java
index 4ecb917069..8b993120d9 100644
--- a/xmlworker/src/main/java/com/itextpdf/tool/xml/pipeline/end/PdfWriterPipeline.java
+++ b/xmlworker/src/main/java/com/itextpdf/tool/xml/pipeline/end/PdfWriterPipeline.java
@@ -46,6 +46,7 @@
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
+import com.itextpdf.text.log.Level;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.pdf.PdfWriter;
@@ -141,7 +142,7 @@ private void write(final WorkerContext context, final ProcessObject po) throws P
if (writable instanceof WritableElement) {
for (Element e : ((WritableElement) writable).elements()) {
try {
- if (!doc.add(e)) {
+ if (!doc.add(e) && LOG.isLogging(Level.TRACE)) {
LOG.trace(String.format(
LocaleMessages.getInstance().getMessage(LocaleMessages.ELEMENT_NOT_ADDED),
e.toString()));
diff --git a/xmlworker/src/test/java/com/itextpdf/tool/xml/BugRunnerTest.java b/xmlworker/src/test/java/com/itextpdf/tool/xml/BugRunnerTest.java
index a6455c8686..39fb23d4d8 100644
--- a/xmlworker/src/test/java/com/itextpdf/tool/xml/BugRunnerTest.java
+++ b/xmlworker/src/test/java/com/itextpdf/tool/xml/BugRunnerTest.java
@@ -76,6 +76,7 @@ public void setup() {
list.add("3353957.html");
list.add("ol-test.html");
list.add("processing-instructions.html");
+ list.add("starcomments.html");
}
@Test
diff --git a/xmlworker/src/test/java/com/itextpdf/tool/xml/examples/custom/StarCommentTest02.java b/xmlworker/src/test/java/com/itextpdf/tool/xml/examples/custom/StarCommentTest02.java
new file mode 100644
index 0000000000..335bacc9ce
--- /dev/null
+++ b/xmlworker/src/test/java/com/itextpdf/tool/xml/examples/custom/StarCommentTest02.java
@@ -0,0 +1,51 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2017 iText Group NV
+ Authors: iText Software.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License version 3
+ as published by the Free Software Foundation with the addition of the
+ following permission added to Section 15 as permitted in Section 7(a):
+ FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
+ ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
+ OF THIRD PARTY RIGHTS
+
+ 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 http://www.gnu.org/licenses or write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA, 02110-1301 USA, or download the license from the following URL:
+ http://itextpdf.com/terms-of-use/
+
+ The interactive user interfaces in modified source and object code versions
+ of this program must display Appropriate Legal Notices, as required under
+ Section 5 of the GNU Affero General Public License.
+
+ In accordance with Section 7(b) of the GNU Affero General Public License,
+ a covered work must retain the producer line in every PDF that is created
+ or manipulated using iText.
+
+ You can be released from the requirements of the license by purchasing
+ a commercial license. Buying such a license is mandatory as soon as you
+ develop commercial activities involving the iText software without
+ disclosing the source code of your own applications.
+ These activities include: offering paid services to customers as an ASP,
+ serving PDFs on the fly in a web application, shipping iText with a closed
+ source product.
+
+ For more information, please contact iText Software Corp. at this
+ address: sales@itextpdf.com
+ */
+package com.itextpdf.tool.xml.examples.custom;
+
+import com.itextpdf.tool.xml.examples.SampleTest;
+
+public class StarCommentTest02 extends SampleTest {
+ protected String getTestName() {
+ return "starComment02";
+ }
+}
diff --git a/xmlworker/src/test/resources/bugs/starcomments.html b/xmlworker/src/test/resources/bugs/starcomments.html
new file mode 100644
index 0000000000..4bd41b8d3e
--- /dev/null
+++ b/xmlworker/src/test/resources/bugs/starcomments.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ http://www.example.com/ * hi
+
+
+
+ /
+
+
\ No newline at end of file
diff --git a/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/background_image_div01.html b/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/background_image_div01.html
index 8c05c59e60..cd7488b2ac 100644
--- a/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/background_image_div01.html
+++ b/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/background_image_div01.html
@@ -6,7 +6,7 @@
texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttextvtexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext
-
+
image from web
texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext
diff --git a/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/itext.png b/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/itext.png
new file mode 100644
index 0000000000..d961f4efac
Binary files /dev/null and b/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/itext.png differ
diff --git a/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/custom/starComment02/starComment02.html b/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/custom/starComment02/starComment02.html
new file mode 100644
index 0000000000..3bc20ab075
--- /dev/null
+++ b/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/custom/starComment02/starComment02.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+* hello world */
+
+
Hello World!
+
+/* hello world */
+
+
+
diff --git a/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/custom/starComment02/starComment02.pdf b/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/custom/starComment02/starComment02.pdf
new file mode 100644
index 0000000000..ef677e8cc6
Binary files /dev/null and b/xmlworker/src/test/resources/com/itextpdf/tool/xml/examples/custom/starComment02/starComment02.pdf differ
diff --git a/xtra/pom.xml b/xtra/pom.xml
index a6b715d74b..f6970d680c 100644
--- a/xtra/pom.xml
+++ b/xtra/pom.xml
@@ -10,7 +10,7 @@
itext-xtra
- 5.5.11
+ 5.5.12iText XtraiText Xtra, part of iText a Free Java-PDF library
@@ -154,18 +154,6 @@
http://developers.itextpdf.com/reference/classes
-
diff --git a/xtra/src/main/java/com/itextpdf/text/pdf/mc/MCParser.java b/xtra/src/main/java/com/itextpdf/text/pdf/mc/MCParser.java
index 0b06dce58c..ccdf043394 100644
--- a/xtra/src/main/java/com/itextpdf/text/pdf/mc/MCParser.java
+++ b/xtra/src/main/java/com/itextpdf/text/pdf/mc/MCParser.java
@@ -54,6 +54,7 @@
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.error_messages.MessageLocalization;
import com.itextpdf.text.io.RandomAccessSourceFactory;
+import com.itextpdf.text.log.Level;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.pdf.ByteBuffer;
@@ -240,8 +241,10 @@ public void parse(PdfDictionary page, PdfIndirectReference pageref) throws IOExc
baos.close();
stream.setData(baos.toByteArray());
// showing how many items are left
- LOGGER.info(String.format("There are %d items left for processing", items.size()));
- }
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("There are %d items left for processing", items.size()));
+ }
+ }
/**
* When an XObject with a StructParent is encountered,
@@ -251,8 +254,10 @@ public void parse(PdfDictionary page, PdfIndirectReference pageref) throws IOExc
protected void dealWithXObj(PdfName xobj) {
PdfDictionary dict = xobjects.getAsStream(xobj);
PdfNumber structParent = dict.getAsNumber(PdfName.STRUCTPARENT);
- LOGGER.info(String.format("Encountered StructParent %s in content", structParent));
- if (structParent == null)
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("Encountered StructParent %s in content", structParent));
+ }
+ if (structParent == null)
return;
StructureItem item = items.get(0);
if (item.checkStructParent(pageref.getNumber(), structParent.intValue()) == 1)
@@ -271,8 +276,10 @@ protected void dealWithMcid(PdfNumber mcid) throws IOException, DocumentExceptio
if (mcid == null)
return;
StructureItem item = items.get(0);
- LOGGER.info(String.format("Encountered MCID %s in content, comparing with %s", mcid, item));
- switch (item.checkMCID(pageref.getNumber(), mcid.intValue())) {
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("Encountered MCID %s in content, comparing with %s", mcid, item));
+ }
+ switch (item.checkMCID(pageref.getNumber(), mcid.intValue())) {
case 0 :
StructureObject obj = (StructureObject)item;
convertToXObject(obj);
diff --git a/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureItems.java b/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureItems.java
index 304e7cbed3..7d757eaf21 100644
--- a/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureItems.java
+++ b/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureItems.java
@@ -50,6 +50,8 @@
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.error_messages.MessageLocalization;
+import com.itextpdf.text.exceptions.InvalidPdfException;
+import com.itextpdf.text.log.Level;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.pdf.PdfArray;
@@ -83,7 +85,7 @@ public class StructureItems extends ArrayList {
* @param reader the reader holding the PDF to examine
*/
public StructureItems(PdfReader reader)
- throws DocumentException {
+ throws DocumentException, InvalidPdfException {
super();
PdfDictionary catalog = reader.getCatalog();
structTreeRoot = catalog.getAsDict(PdfName.STRUCTTREEROOT);
@@ -117,8 +119,10 @@ public StructureItems(PdfReader reader)
* @param ref the reference to the StructElem dictionary
* @throws DocumentException
*/
- protected void processStructElems(PdfDictionary structElem, PdfIndirectReference ref) {
- LOGGER.info(String.format("addStructureItems(%s, %s)", structElem, ref));
+ protected void processStructElems(PdfDictionary structElem, PdfIndirectReference ref) throws InvalidPdfException {
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("addStructureItems(%s, %s)", structElem, ref));
+ }
if (structElem == null)
return;
processStructElemKids(structElem, ref, structElem.getDirectObject(PdfName.K));
@@ -132,8 +136,10 @@ protected void processStructElems(PdfDictionary structElem, PdfIndirectReference
* @param ref the reference to the StructElem dictionary
* @param object the kids object
*/
- protected void processStructElemKids(PdfDictionary structElem, PdfIndirectReference ref, PdfObject object) {
- LOGGER.info(String.format("addStructureItem(%s, %s, %s)", structElem, ref, object));
+ protected void processStructElemKids(PdfDictionary structElem, PdfIndirectReference ref, PdfObject object) throws InvalidPdfException {
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("addStructureItem(%s, %s, %s)", structElem, ref, object));
+ }
if (object == null)
return;
StructureItem item;
diff --git a/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureMCID.java b/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureMCID.java
index f04b731f5a..59def64c00 100644
--- a/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureMCID.java
+++ b/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureMCID.java
@@ -63,7 +63,7 @@ public class StructureMCID extends StructureItem {
* @param mcid an MCID
*/
public StructureMCID(PdfIndirectReference pg, PdfNumber mcid) {
- this.pageref = pg.getNumber();
+ this.pageref = pg == null ? -1 : pg.getNumber();
this.mcid = mcid.intValue();
}
diff --git a/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureObject.java b/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureObject.java
index 3138412265..2f6d8804b5 100644
--- a/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureObject.java
+++ b/xtra/src/main/java/com/itextpdf/text/pdf/mc/StructureObject.java
@@ -43,10 +43,8 @@
*/
package com.itextpdf.text.pdf.mc;
-import com.itextpdf.text.pdf.PdfDictionary;
-import com.itextpdf.text.pdf.PdfIndirectReference;
-import com.itextpdf.text.pdf.PdfName;
-import com.itextpdf.text.pdf.PdfObject;
+import com.itextpdf.text.exceptions.InvalidPdfException;
+import com.itextpdf.text.pdf.*;
/**
* A StructureItem that refers to an object from an OBJR dictionary.
@@ -70,12 +68,15 @@ public class StructureObject extends StructureItem {
* @param ref the reference of the parent structure element
* @param dict the object reference dictionary
*/
- public StructureObject(PdfDictionary structElem, PdfIndirectReference ref, PdfDictionary dict) {
+ public StructureObject(PdfDictionary structElem, PdfIndirectReference ref, PdfDictionary dict) throws InvalidPdfException {
this.structElem = structElem;
this.ref = ref;
this.obj = dict.getDirectObject(PdfName.OBJ);
this.objref = dict.getAsIndirectObject(PdfName.OBJ);
- this.structParent = ((PdfDictionary)obj).getAsNumber(PdfName.STRUCTPARENT).intValue();
+ PdfNumber sp = ((PdfDictionary)obj).getAsNumber(PdfName.STRUCTPARENT);
+ if(sp == null)
+ throw new InvalidPdfException("");
+ this.structParent = sp.intValue();
PdfIndirectReference pg = dict.getAsIndirectObject(PdfName.PG);
if (pg == null)
pg = structElem.getAsIndirectObject(PdfName.PG);
diff --git a/xtra/src/main/java/com/itextpdf/text/pdf/pdfcleanup/PdfCleanUpContentOperator.java b/xtra/src/main/java/com/itextpdf/text/pdf/pdfcleanup/PdfCleanUpContentOperator.java
index 58549fcddc..5087cafaf6 100644
--- a/xtra/src/main/java/com/itextpdf/text/pdf/pdfcleanup/PdfCleanUpContentOperator.java
+++ b/xtra/src/main/java/com/itextpdf/text/pdf/pdfcleanup/PdfCleanUpContentOperator.java
@@ -157,8 +157,6 @@ public void invoke(PdfContentStreamProcessor pdfContentStreamProcessor, PdfLiter
disableOutput = true;
}
}
- } else if (lineStyleOperators.contains(operatorStr)) {
- disableOutput = true;
} else if (textShowingOperators.contains(operatorStr) && !allChunksAreVisible(cleanUpStrategy.getChunks())) {
disableOutput = true;
diff --git a/xtra/src/main/java/com/itextpdf/text/pdf/util/SmartPdfSplitter.java b/xtra/src/main/java/com/itextpdf/text/pdf/util/SmartPdfSplitter.java
index 1d05ce14a0..00e29f2f14 100644
--- a/xtra/src/main/java/com/itextpdf/text/pdf/util/SmartPdfSplitter.java
+++ b/xtra/src/main/java/com/itextpdf/text/pdf/util/SmartPdfSplitter.java
@@ -45,6 +45,7 @@
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.log.Level;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.pdf.PdfCopy;
@@ -71,7 +72,9 @@ public SmartPdfSplitter(PdfReader reader) throws IOException {
this.reader = reader;
reader.setAppendable(true);
numberOfPages = reader.getNumberOfPages();
- LOGGER.info(String.format("Creating a splitter for a document with %s pages", numberOfPages));
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("Creating a splitter for a document with %s pages", numberOfPages));
+ }
}
public boolean hasMorePages() {
@@ -102,13 +105,17 @@ public boolean split(OutputStream os, long sizeInBytes) throws IOException, Docu
page = counter.getLength(resources);
resources = counter.getResources();
length += page + trailer + xrefLength(resources.size());
- LOGGER.info(String.format("Page %s: Comparing %s with %s", currentPage, length, sizeInBytes));
- LOGGER.info(String.format(" page %s trailer %s xref %s", page, trailer, xrefLength(resources.size())));
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("Page %s: Comparing %s with %s", currentPage, length, sizeInBytes));
+ LOGGER.info(String.format(" page %s trailer %s xref %s", page, trailer, xrefLength(resources.size())));
+ }
if (!hasPage || length < sizeInBytes) {
hasPage = true;
copy.addPage(copy.getImportedPage(reader, currentPage));
length = copy.getOs().getCounter();
- LOGGER.info(String.format("Size after adding page: %s", length));
+ if (LOGGER.isLogging(Level.INFO)) {
+ LOGGER.info(String.format("Size after adding page: %s", length));
+ }
if (length > sizeInBytes) overSized = true;
currentPage++;
}
diff --git a/xtra/src/test/java/com/itextpdf/text/pdf/pdfcleanup/PdfCleanUpProcessorTest.java b/xtra/src/test/java/com/itextpdf/text/pdf/pdfcleanup/PdfCleanUpProcessorTest.java
index dd75b35988..24a2368293 100644
--- a/xtra/src/test/java/com/itextpdf/text/pdf/pdfcleanup/PdfCleanUpProcessorTest.java
+++ b/xtra/src/test/java/com/itextpdf/text/pdf/pdfcleanup/PdfCleanUpProcessorTest.java
@@ -89,6 +89,7 @@ public static Collection data() {
List cleanUpLocations2 = Arrays.asList(new PdfCleanUpLocation(1, new Rectangle(97f, 405f, 480f, 445f), BaseColor.GRAY));
List cleanUpLocations3 = Arrays.asList(new PdfCleanUpLocation(1, new Rectangle(97f, 605f, 480f, 645f), BaseColor.GRAY));
List cleanUpLocations4 = Arrays.asList(new PdfCleanUpLocation(1, new Rectangle(212, 394, 212 + 186, 394 + 170), null));
+ List cleanUpLocations5= Arrays.asList(new PdfCleanUpLocation(1, new Rectangle(0f, 0f, 595f, 680f), BaseColor.GRAY));
return Arrays.asList(new Object[][] {{"page229.pdf", "page229_01.pdf", "cmp_page229_01.pdf", cleanUpLocations1},
{"page229-modified-Tc-Tw.pdf", "page229-modified-Tc-Tw.pdf", "cmp_page229-modified-Tc-Tw.pdf", cleanUpLocations1},
@@ -118,6 +119,8 @@ public static Collection data() {
{"absentICentry.pdf", "absentICentry.pdf", "cmp_absentICentry.pdf", null},
{"lotOfDashes.pdf", "lotOfDashes.pdf", "cmp_lotOfDashes.pdf", null},
{"clipPathReduction.pdf", "clipPathReduction.pdf", "cmp_clipPathReduction.pdf", cleanUpLocations4},
+ {"helloHelvetica.pdf", "helloHelvetica.pdf", "cmp_helloHelvetica.pdf", cleanUpLocations5},
+
});
}
diff --git a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedBezier.pdf b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedBezier.pdf
index 6912938612..69785bcd95 100644
Binary files a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedBezier.pdf and b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedBezier.pdf differ
diff --git a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedClosedRotatedTriangles.pdf b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedClosedRotatedTriangles.pdf
index d3de292d14..27a64fbae8 100644
Binary files a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedClosedRotatedTriangles.pdf and b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedClosedRotatedTriangles.pdf differ
diff --git a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedStyledClosedBezier.pdf b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedStyledClosedBezier.pdf
index 53954703a8..cd850e07af 100644
Binary files a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedStyledClosedBezier.pdf and b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_dashedStyledClosedBezier.pdf differ
diff --git a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_degenerateCases.pdf b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_degenerateCases.pdf
index f587b7c978..a76b247d0e 100644
Binary files a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_degenerateCases.pdf and b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_degenerateCases.pdf differ
diff --git a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_helloHelvetica.pdf b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_helloHelvetica.pdf
new file mode 100644
index 0000000000..84fc609ba5
Binary files /dev/null and b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_helloHelvetica.pdf differ
diff --git a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_lotOfDashes.pdf b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_lotOfDashes.pdf
index cc3719a15c..f7267c9067 100644
Binary files a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_lotOfDashes.pdf and b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_lotOfDashes.pdf differ
diff --git a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_miterTest.pdf b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_miterTest.pdf
index 60047c0238..f027f975f8 100644
Binary files a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_miterTest.pdf and b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_miterTest.pdf differ
diff --git a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_styledLineArts.pdf b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_styledLineArts.pdf
index d5c081b14f..e2b7952d7c 100644
Binary files a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_styledLineArts.pdf and b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/cmp_styledLineArts.pdf differ
diff --git a/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/helloHelvetica.pdf b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/helloHelvetica.pdf
new file mode 100644
index 0000000000..d42e7c2588
Binary files /dev/null and b/xtra/src/test/resources/com/itextpdf/text/pdf/pdfcleanup/helloHelvetica.pdf differ