diff --git a/BUILDING.md b/BUILDING.md index 30dc49328..1d4272ce6 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1,18 +1 @@ -To build iText, Maven must be installed: http://maven.apache.org/ - -Running install without a profile will generate the itextpdf jar: - -```mvn install``` - -When using the profile 'all' also the source and javadoc jars will be generated: - -```mvn install -P all``` - -If you are in need of the asian font jars, you can run one of the following commands: - -```mvn clean install -f itext-asian.pom``` -```mvn clean install -f itext-asiancmaps.pom``` - -If you need the hyphenation jar, execute: - -```mvn clean install -f itext-hyph-xml.pom``` +To build **iText 5 .NET** (aka iTextSharp), you need to build `src/BuildAll.sln`. diff --git a/README.md b/README.md index 698594436..d96cdf524 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 @@ -39,3 +39,4 @@ Contact sales for more info: http://itextpdf.com/sales [agpl]: LICENSE.md [building]: BUILDING.md [contributing]: CONTRIBUTING.md +[gratis]: https://en.wikipedia.org/wiki/Gratis_versus_libre \ No newline at end of file diff --git a/src/core/AssemblyInfo.cs b/src/core/AssemblyInfo.cs index 7c38c78ed..4ce92ea0b 100644 --- a/src/core/AssemblyInfo.cs +++ b/src/core/AssemblyInfo.cs @@ -16,4 +16,4 @@ [assembly: ComVisibleAttribute(false)] -[assembly: AssemblyVersion("5.5.11")] +[assembly: AssemblyVersion("5.5.12")] diff --git a/src/core/iTextSharp/text/Version.cs b/src/core/iTextSharp/text/Version.cs index 7d1382dad..3b97bf710 100644 --- a/src/core/iTextSharp/text/Version.cs +++ b/src/core/iTextSharp/text/Version.cs @@ -72,7 +72,7 @@ public sealed class Version { * This String contains the version number of this iText release. * For debugging purposes, we request you NOT to change this constant. */ - static private String release = "5.5.11"; + static private String release = "5.5.12"; /** * This String contains the iText version as shown in the producer line. diff --git a/src/core/iTextSharp/text/error_messages/en.lng b/src/core/iTextSharp/text/error_messages/en.lng index 9acb0ee18..3008b3970 100644 --- a/src/core/iTextSharp/text/error_messages/en.lng +++ b/src/core/iTextSharp/text/error_messages/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/src/core/iTextSharp/text/error_messages/nl.lng b/src/core/iTextSharp/text/error_messages/nl.lng index 3e149cbf7..9d03dbf02 100644 --- a/src/core/iTextSharp/text/error_messages/nl.lng +++ b/src/core/iTextSharp/text/error_messages/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/src/core/iTextSharp/text/pdf/AcroFields.cs b/src/core/iTextSharp/text/pdf/AcroFields.cs index 77007299c..6ba783b53 100644 --- a/src/core/iTextSharp/text/pdf/AcroFields.cs +++ b/src/core/iTextSharp/text/pdf/AcroFields.cs @@ -1760,7 +1760,7 @@ virtual public bool RemoveField(String name, int page) { PdfIndirectReference kid = refi; while ((refi = wd.GetAsIndirectObject(PdfName.PARENT)) != null) { wd = wd.GetAsDict( PdfName.PARENT ); - //if (wd == null) break; //avoid null-reference exceptions in case of removing fields with kids (see SUP-1846) + if (wd == null) break; //avoid null-reference exceptions in case of removing fields with kids (see SUP-1846) PdfArray kids = wd.GetAsArray(PdfName.KIDS); if (RemoveRefFromArray(kids, kid) != 0) break; diff --git a/src/core/iTextSharp/text/pdf/BarcodeDatamatrix.cs b/src/core/iTextSharp/text/pdf/BarcodeDatamatrix.cs index fada5f852..4ca0fdfbc 100644 --- a/src/core/iTextSharp/text/pdf/BarcodeDatamatrix.cs +++ b/src/core/iTextSharp/text/pdf/BarcodeDatamatrix.cs @@ -87,6 +87,12 @@ public class BarcodeDatamatrix { /** * X21 encodation. */ + public const int DM_X12 = 5; + /** + * X12 encodation. + * + * @deprecated Use {@link BarcodeDataMatrix#DM_X12} instead. + */ public const int DM_X21 = 5; /** * EDIFACT encodation. @@ -106,6 +112,28 @@ public class BarcodeDatamatrix { */ public const int DM_TEST = 64; + private const byte LATCH_B256 = (byte)231; + + private const byte LATCH_EDIFACT = (byte)240; + + private const byte LATCH_X12 = (byte)238; + + private const byte LATCH_TEXT = (byte)239; + + private const byte LATCH_C40 = (byte)230; + + private const byte UNLATCH = (byte)254; + + private const byte EXTENDED_ASCII = (byte)235; + + private const byte PADDING = (byte)129; + + private string encoding; + + public const String DEFAULT_DATA_MATRIX_ENCODING = "iso-8859-1"; + + + private static readonly DmParams[] dmSizes = { new DmParams(10, 10, 10, 10, 3, 3, 5), new DmParams(12, 12, 12, 12, 5, 5, 7), @@ -138,7 +166,7 @@ public class BarcodeDatamatrix { new DmParams(132, 132, 22, 22, 1304, 163, 62), new DmParams(144, 144, 24, 24, 1558, 156, 62)}; - private const String x12 = "\r*> 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + private const String X12 = "\r*> 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private int extOut; private short[] place; private byte[] image; @@ -148,12 +176,27 @@ public class BarcodeDatamatrix { private int options; private bool forceSquareSize = false; + // 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; + /** * Creates an instance of this class. */ public BarcodeDatamatrix() { + encoding = DEFAULT_DATA_MATRIX_ENCODING; } + public BarcodeDatamatrix(String code) { + encoding = DEFAULT_DATA_MATRIX_ENCODING; + Generate(code); + } + public BarcodeDatamatrix(String code, String encoding) { + this.encoding = encoding; + Generate(code); + } private void SetBit(int x, int y, int xByte) { image[y * xByte + x / 8] |= (byte)(128 >> (x & 7)); } @@ -194,7 +237,7 @@ private void Draw(byte[] data, int dataSize, DmParams dm) { for (xs = 0; xs < dm.width; xs += dm.widthSection) { for (x = 1; x < dm.widthSection - 1; ++x) { z = place[p++]; - if (z == 1 || (z > 1 && ((data[z/8-1] & 0xff) & (128 >> (z%8))) != 0)) + if (z == 1 || (z > 1 && ((data[z / 8 - 1] & 0xff) & (128 >> (z % 8))) != 0)) SetBit(x + xs + ws, y + ys + ws, xByte); } } @@ -206,7 +249,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) @@ -218,67 +261,104 @@ private static void MakePadding(byte[] data, int position, int count) { private static bool 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[dataOffset + 1] = (byte)(textLength / 250 + 249); - data[dataOffset + 2] = (byte)(textLength % 250); - k = 3; - } - System.Array.Copy(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; - - } - return k - dataOffset; + data[simulatedDataOffset + 1] = (byte)(textLength / 250 + 249); + data[simulatedDataOffset + 2] = (byte)(textLength % 250); + minRequiredDataIncrement = prevEnc != DM_B256 ? 3 : 0; + } + if (prevEnc == DM_B256) + textLength = 1; + System.Array.Copy(text, textOffset, data, minRequiredDataIncrement + dataOffset, textLength); + for (int j = prevEnc != DM_B256 ? dataOffset + 1 : dataOffset; j < minRequiredDataIncrement + textLength + dataOffset; ++j) { + RandomizationAlgorithm255(data, j); + } + if (prevEnc == DM_B256) + RandomizationAlgorithm255(data, simulatedDataOffset + 1); + return textLength + dataOffset + minRequiredDataIncrement - origDataOffset; } - 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 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 symbolIndex, int prevEnc, int origDataOffset) { + int ptrIn, ptrOut, count, k, n; + Boolean latch = true; byte c; if (textLength == 0) return 0; @@ -287,7 +367,7 @@ 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; ++count; @@ -295,25 +375,25 @@ private static int X12Encodation(byte[] text, int textOffset, int textLength, by else { x[ptrIn] = 100; if (count >= 6) - count -= (count / 3) * 3; + count -= count / 3 * 3; for (k = 0; k < count; ++k) x[ptrIn - k - 1] = 100; count = 0; } } if (count >= 6) - count -= (count / 3) * 3; + count -= count / 3 * 3; for (k = 0; k < count; ++k) x[ptrIn - k - 1] = 100; ptrIn = 0; 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; @@ -322,29 +402,68 @@ private static int X12Encodation(byte[] text, int textOffset, int textLength, by 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; + 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; @@ -352,14 +471,144 @@ private static int EdifactEncodation(byte[] text, int textOffset, int textLength ptrOut = 0; edi = 0; pedi = 18; - bool ascii = true; + 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 = Int32.MaxValue; + 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; @@ -369,37 +618,17 @@ private static int EdifactEncodation(byte[] text, int textOffset, int textLength break; data[dataOffset + ptrOut++] = (byte)(edi >> 16); data[dataOffset + ptrOut++] = (byte)(edi >> 8); - data[dataOffset + ptrOut++] = (byte) edi; + data[dataOffset + ptrOut++] = (byte)edi; edi = 0; pedi = 18; - } else - pedi -= 6; - } else { - int dataSize = int.MaxValue; - 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 <= 12) { - byte val = (byte) ((edi >> 18) & 0x3F); - if ((val & 0x20) == 0) - val |= 0x40; - 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); - } - } else if (!ascii) { + else + pedi -= 6; + } + else { + if (!ascii) { edi |= ('_' & 0x3f) << pedi; - if (ptrOut + (3 - pedi/8) > dataLength) + if (ptrOut + 3 - pedi / 8 > dataLength) break; data[dataOffset + ptrOut++] = (byte)(edi >> 16); if (pedi <= 12) @@ -410,22 +639,51 @@ private static int EdifactEncodation(byte[] text, int textOffset, int textLength 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; - if (!ascii) { + if (!sizeFixed && (symbolIndex == text.Length - 1 || symbolIndex < 0)) { + dataSize = Int32.MaxValue; + 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) { + 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); + } + if (pedi <= 6) { + byte val = (byte)((edi >> 12) & 0x3F); + if ((val & 0x20) == 0) + val |= 0x40; + data[dataOffset + ptrOut++] = (byte)(val + 1); + } + } + else if (!ascii) { edi |= ('_' & 0x3f) << pedi; - if (ptrOut + (3 - pedi / 8) > dataLength) + if (ptrOut + 3 - pedi / 8 > dataLength) return -1; data[dataOffset + ptrOut++] = (byte)(edi >> 16); if (pedi <= 12) @@ -433,35 +691,118 @@ private static int EdifactEncodation(byte[] text, int textOffset, int textLength if (pedi <= 6) 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, bool c40) { + private static int C40OrTextEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength, bool 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{|}~\u007f"; + shift3 = "`abcdefghijklmnopqrstuvwxyz{|}~\\177"; } else { basic = " 0123456789abcdefghijklmnopqrstuvwxyz"; - shift3 = "`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\u007f"; + 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; last1 = 0; while (ptrIn < textLength) { - if ((encPtr % 3) == 0) { + if (encPtr % 3 == 0) { last0 = ptrIn; last1 = encPtr; } @@ -488,7 +829,7 @@ private static int C40OrTextEncodation(byte[] text, int textOffset, int textLeng enc[encPtr++] = idx; } } - if ((encPtr % 3) != 0) { + if (encPtr % 3 != 0) { ptrIn = last0; encPtr = last1; } @@ -501,80 +842,131 @@ private static int C40OrTextEncodation(byte[] text, int textOffset, int textLeng 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 GetEncodation(byte[] text, int textOffset, int textSize, byte[] data, int dataOffset, int dataSize, int options, bool firstMatch) { - int e, j, k; - int[] e1 = new int[6]; + private static int MinValueInColumn(int[][] array, int column) { + int min = Int32.MaxValue; + for (int i = 0; i < 6; i++) + if (array[i][column] < min && array[i][column] >= 0) + min = array[i][column]; + return min != Int32.MaxValue ? min : -1; + } + + 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] = Int32.MaxValue; + } + 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] == Int32.MaxValue) { + 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; + int length = data.Length; + byte[][] dataDynamic = new byte[6][]; + for (int i = 0; i < dataDynamic.Length; i++) { + dataDynamic[i] = new byte[length]; + } + for (int i = 0; i < 6; i++) { + System.Array.Copy(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] : Int32.MaxValue; + } + for (int currEnc = 0; currEnc < 6; currEnc++) { + + byte[][] dataDynamicInner = new byte[6][]; + for (int l = 0; l < dataDynamicInner.Length; l++) { + dataDynamicInner[l] = new byte[length]; + } + for (int prevEnc = 0; prevEnc < 6; prevEnc++) { + System.Array.Copy(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.Array.Copy(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.Array.Copy(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.Array.Copy(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.Array.Copy(text, textOffset, data, dataOffset, textSize); + return textSize; } return -1; } @@ -583,7 +975,7 @@ private static int GetNumber(byte[] text, int ptrIn, int n) { int v, j, c; v = 0; for (j = 0; j < n; ++j) { - c = text[ptrIn++] &0xff; + c = text[ptrIn++] & 0xff; if (c < '0' || c > '9') return -1; v = v * 10 + c - '0'; @@ -601,75 +993,75 @@ private int ProcessExtensions(byte[] text, int textOffset, int textSize, byte[] while (ptrIn < textSize) { if (order > 20) return -1; - c = text[textOffset + ptrIn++] &0xff; + c = text[textOffset + ptrIn++] & 0xff; ++order; switch (c) { - case '.': - extOut = ptrIn; - return ptrOut; - case 'e': - if (ptrIn + 6 > textSize) - return -1; - eci = GetNumber(text, textOffset + ptrIn, 6); - if (eci < 0) - return -1; - ptrIn += 6; - data[ptrOut++] = (byte)241; - if (eci < 127) - data[ptrOut++] = (byte)(eci + 1); - else if (eci < 16383) { - data[ptrOut++] = (byte)((eci - 127) / 254 + 128); - data[ptrOut++] = (byte)(((eci - 127) % 254) + 1); - } - else { - data[ptrOut++] = (byte)((eci - 16383) / 64516 + 192); - data[ptrOut++] = (byte)((((eci - 16383) / 254) % 254) + 1); - data[ptrOut++] = (byte)(((eci - 16383) % 254) + 1); - } - break; - case 's': - if (order != 1) - return -1; - if (ptrIn + 9 > textSize) - return -1; - fn = GetNumber(text, textOffset + ptrIn, 2); - if (fn <= 0 || fn > 16) - return -1; - ptrIn += 2; - ft = GetNumber(text, textOffset + ptrIn, 2); - if (ft <= 1 || ft > 16) - return -1; - ptrIn += 2; - fi = GetNumber(text, textOffset + ptrIn, 5); - if (fi < 0 || fn >= 64516) - return -1; - ptrIn += 5; - data[ptrOut++] = (byte)(233); - data[ptrOut++] = (byte)(((fn - 1) << 4) | (17 - ft)); - data[ptrOut++] = (byte)(fi / 254 + 1); - data[ptrOut++] = (byte)((fi % 254) + 1); - break; - case 'p': - if (order != 1) - return -1; - data[ptrOut++] = (byte)(234); - break; - case 'm': - if (order != 1) - return -1; - if (ptrIn + 1 > textSize) - return -1; - c = text[textOffset + ptrIn++] &0xff; - if (c != '5' && c != '5') - return -1; - data[ptrOut++] = (byte)(234); - data[ptrOut++] = (byte)(c == '5' ? 236 : 237); - break; - case 'f': - if (order != 1 && (order != 2 || (text[textOffset] != 's' && text[textOffset] != 'm'))) - return -1; - data[ptrOut++] = (byte)(232); - break; + case '.': + extOut = ptrIn; + return ptrOut; + case 'e': + if (ptrIn + 6 > textSize) + return -1; + eci = GetNumber(text, textOffset + ptrIn, 6); + if (eci < 0) + return -1; + ptrIn += 6; + data[ptrOut++] = (byte)241; + if (eci < 127) + data[ptrOut++] = (byte)(eci + 1); + else if (eci < 16383) { + data[ptrOut++] = (byte)((eci - 127) / 254 + 128); + data[ptrOut++] = (byte)(((eci - 127) % 254) + 1); + } + else { + data[ptrOut++] = (byte)((eci - 16383) / 64516 + 192); + data[ptrOut++] = (byte)((((eci - 16383) / 254) % 254) + 1); + data[ptrOut++] = (byte)(((eci - 16383) % 254) + 1); + } + break; + case 's': + if (order != 1) + return -1; + if (ptrIn + 9 > textSize) + return -1; + fn = GetNumber(text, textOffset + ptrIn, 2); + if (fn <= 0 || fn > 16) + return -1; + ptrIn += 2; + ft = GetNumber(text, textOffset + ptrIn, 2); + if (ft <= 1 || ft > 16) + return -1; + ptrIn += 2; + fi = GetNumber(text, textOffset + ptrIn, 5); + if (fi < 0 || fn >= 64516) + return -1; + ptrIn += 5; + data[ptrOut++] = (byte)(233); + data[ptrOut++] = (byte)(((fn - 1) << 4) | (17 - ft)); + data[ptrOut++] = (byte)(fi / 254 + 1); + data[ptrOut++] = (byte)((fi % 254) + 1); + break; + case 'p': + if (order != 1) + return -1; + data[ptrOut++] = (byte)(234); + break; + case 'm': + if (order != 1) + return -1; + if (ptrIn + 1 > textSize) + return -1; + c = text[textOffset + ptrIn++] & 0xff; + if (c != '5' && c != '5') + return -1; + data[ptrOut++] = (byte)(234); + data[ptrOut++] = (byte)(c == '5' ? 236 : 237); + break; + case 'f': + if (order != 1 && (order != 2 || (text[textOffset] != 's' && text[textOffset] != 'm'))) + return -1; + data[ptrOut++] = (byte)(232); + break; } } return -1; @@ -687,10 +1079,29 @@ private int ProcessExtensions(byte[] text, int textOffset, int textSize, byte[] * @throws java.io.UnsupportedEncodingException on error */ virtual public int Generate(String text) { - byte[] t = System.Text.Encoding.GetEncoding(1252).GetBytes(text); + byte[] t = System.Text.Encoding.GetEncoding(encoding).GetBytes(text); + return Generate(t, 0, t.Length); } - + + /** + * Creates a barcode. The String is interpreted with the ISO-8859-1 encoding + * @param text the text to encode into + * @param + * @return the status of the generation. It can be one of this values: + *

+ * DM_NO_ERROR - no error.
+ * DM_ERROR_TEXT_TOO_BIG - the text is too big for the symbology capabilities.
+ * DM_ERROR_INVALID_SQUARE - the dimensions given for the symbol are illegal.
+ * DM_ERROR_EXTENSION - an error was while parsing an extension. + * @throws java.io.UnsupportedEncodingException on error + */ + virtual public int Generate(String text, String encoding) { + byte[] t = System.Text.Encoding.GetEncoding(encoding).GetBytes(text); + + return Generate(t, 0, t.Length); + } + /** * Creates a barcode. * @param text the text @@ -713,6 +1124,15 @@ virtual public int Generate(byte[] text, int textOffset, int textSize) { return DM_ERROR_EXTENSION; } e = -1; + + int innerSize = textSize - extOut; + f = new int[6][]; + switchMode = new int[6][]; + for (int i = 0; i < f.Length; i++) { + f[i] = new int[innerSize]; + switchMode[i] = new int[innerSize]; + } + if (height == 0 || width == 0) { last = dmSizes[dmSizes.Length - 1]; e = GetEncodation(text, textOffset + extOut, textSize - extOut, data, extCount, last.dataSize - extCount, options, false); @@ -721,7 +1141,7 @@ virtual 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]; @@ -756,29 +1176,29 @@ virtual public int Generate(byte[] text, int textOffset, int textSize) { } virtual public void PlaceBarcode(PdfContentByte cb, BaseColor foreground, float moduleHeight, float moduleWidth) { - int w = width + 2*ws; - int h = height + 2*ws; - int stride = (w + 7)/8; + int w = width + 2 * ws; + int h = height + 2 * ws; + int stride = (w + 7) / 8; int ptr = 0; cb.SetColorFill(foreground); for (int k = 0; k < h; ++k) { - int p = k*stride; + int p = k * stride; for (int j = 0; j < w; ++j) { - int b = image[p + j/8] & 0xff; - b <<= j%8; + int b = image[p + j / 8] & 0xff; + b <<= j % 8; if ((b & 0x80) != 0) { - cb.Rectangle(j*moduleWidth, (h - k - 1)*moduleHeight, moduleWidth, moduleHeight); + cb.Rectangle(j * moduleWidth, (h - k - 1) * moduleHeight, moduleWidth, moduleHeight); } } } cb.Fill(); } - + /** Gets an Image with the barcode. A successful call to the method generate() * before calling this method is required. * @return the barcode Image * @throws BadElementException on error - */ + */ virtual public Image CreateImage() { if (image == null) return null; @@ -793,7 +1213,7 @@ virtual public Image CreateImage() { * @param foreground the color of the bars * @param background the color of the background * @return the image - */ + */ public virtual System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background) { if (image == null) return null; @@ -994,11 +1414,11 @@ internal class Placement { private int nrow; private int ncol; private short[] array; - private static Dictionary cache = new Dictionary(); + private static Dictionary cache = new Dictionary(); - private Placement() { + private Placement() { } - + internal static short[] DoPlacement(int nrow, int ncol) { int key = nrow * 1000 + ncol; lock (cache) { @@ -1019,64 +1439,64 @@ internal static short[] DoPlacement(int nrow, int ncol) { /* "module" places "chr+bit" with appropriate wrapping within array[] */ private void Module(int row, int col, int chr, int bit) { - if (row < 0) { row += nrow; col += 4 - ((nrow+4)%8); } - if (col < 0) { col += ncol; row += 4 - ((ncol+4)%8); } - array[row*ncol+col] = (short)(8*chr + bit); + if (row < 0) { row += nrow; col += 4 - ((nrow + 4) % 8); } + if (col < 0) { col += ncol; row += 4 - ((ncol + 4) % 8); } + array[row * ncol + col] = (short)(8 * chr + bit); } /* "utah" places the 8 bits of a utah-shaped symbol character in ECC200 */ - private void Utah(int row, int col, int chr) { - Module(row-2,col-2,chr,0); - Module(row-2,col-1,chr,1); - Module(row-1,col-2,chr,2); - Module(row-1,col-1,chr,3); - Module(row-1,col,chr,4); - Module(row,col-2,chr,5); - Module(row,col-1,chr,6); - Module(row,col,chr,7); + private void Utah(int row, int col, int chr) { + Module(row - 2, col - 2, chr, 0); + Module(row - 2, col - 1, chr, 1); + Module(row - 1, col - 2, chr, 2); + Module(row - 1, col - 1, chr, 3); + Module(row - 1, col, chr, 4); + Module(row, col - 2, chr, 5); + Module(row, col - 1, chr, 6); + Module(row, col, chr, 7); } /* "cornerN" places 8 bits of the four special corner cases in ECC200 */ - private void Corner1(int chr) { - Module(nrow-1,0,chr,0); - Module(nrow-1,1,chr,1); - Module(nrow-1,2,chr,2); - Module(0,ncol-2,chr,3); - Module(0,ncol-1,chr,4); - Module(1,ncol-1,chr,5); - Module(2,ncol-1,chr,6); - Module(3,ncol-1,chr,7); - } - private void Corner2(int chr){ - Module(nrow-3,0,chr,0); - Module(nrow-2,0,chr,1); - Module(nrow-1,0,chr,2); - Module(0,ncol-4,chr,3); - Module(0,ncol-3,chr,4); - Module(0,ncol-2,chr,5); - Module(0,ncol-1,chr,6); - Module(1,ncol-1,chr,7); - } - private void Corner3(int chr){ - Module(nrow-3,0,chr,0); - Module(nrow-2,0,chr,1); - Module(nrow-1,0,chr,2); - Module(0,ncol-2,chr,3); - Module(0,ncol-1,chr,4); - Module(1,ncol-1,chr,5); - Module(2,ncol-1,chr,6); - Module(3,ncol-1,chr,7); - } - private void Corner4(int chr){ - Module(nrow-1,0,chr,0); - Module(nrow-1,ncol-1,chr,1); - Module(0,ncol-3,chr,2); - Module(0,ncol-2,chr,3); - Module(0,ncol-1,chr,4); - Module(1,ncol-3,chr,5); - Module(1,ncol-2,chr,6); - Module(1,ncol-1,chr,7); + private void Corner1(int chr) { + Module(nrow - 1, 0, chr, 0); + Module(nrow - 1, 1, chr, 1); + Module(nrow - 1, 2, chr, 2); + Module(0, ncol - 2, chr, 3); + Module(0, ncol - 1, chr, 4); + Module(1, ncol - 1, chr, 5); + Module(2, ncol - 1, chr, 6); + Module(3, ncol - 1, chr, 7); + } + private void Corner2(int chr) { + Module(nrow - 3, 0, chr, 0); + Module(nrow - 2, 0, chr, 1); + Module(nrow - 1, 0, chr, 2); + Module(0, ncol - 4, chr, 3); + Module(0, ncol - 3, chr, 4); + Module(0, ncol - 2, chr, 5); + Module(0, ncol - 1, chr, 6); + Module(1, ncol - 1, chr, 7); + } + private void Corner3(int chr) { + Module(nrow - 3, 0, chr, 0); + Module(nrow - 2, 0, chr, 1); + Module(nrow - 1, 0, chr, 2); + Module(0, ncol - 2, chr, 3); + Module(0, ncol - 1, chr, 4); + Module(1, ncol - 1, chr, 5); + Module(2, ncol - 1, chr, 6); + Module(3, ncol - 1, chr, 7); + } + private void Corner4(int chr) { + Module(nrow - 1, 0, chr, 0); + Module(nrow - 1, ncol - 1, chr, 1); + Module(0, ncol - 3, chr, 2); + Module(0, ncol - 2, chr, 3); + Module(0, ncol - 1, chr, 4); + Module(1, ncol - 3, chr, 5); + Module(1, ncol - 2, chr, 6); + Module(1, ncol - 1, chr, 7); } /* "ECC200" fills an nrow x ncol array with appropriate values for ECC200 */ - private void Ecc200(){ + private void Ecc200() { int row, col, chr; /* First, fill the array[] with invalid entries */ for (int k = 0; k < array.Length; ++k) @@ -1086,35 +1506,35 @@ private void Ecc200(){ do { /* repeatedly first check for one of the special corner cases, then... */ if ((row == nrow) && (col == 0)) Corner1(chr++); - if ((row == nrow-2) && (col == 0) && (ncol%4 != 0)) Corner2(chr++); - if ((row == nrow-2) && (col == 0) && (ncol%8 == 4)) Corner3(chr++); - if ((row == nrow+4) && (col == 2) && (ncol%8 == 0)) Corner4(chr++); + if ((row == nrow - 2) && (col == 0) && (ncol % 4 != 0)) Corner2(chr++); + if ((row == nrow - 2) && (col == 0) && (ncol % 8 == 4)) Corner3(chr++); + if ((row == nrow + 4) && (col == 2) && (ncol % 8 == 0)) Corner4(chr++); /* sweep upward diagonally, inserting successive characters,... */ do { - if ((row < nrow) && (col >= 0) && array[row*ncol+col] == 0) - Utah(row,col,chr++); + if ((row < nrow) && (col >= 0) && array[row * ncol + col] == 0) + Utah(row, col, chr++); row -= 2; col += 2; } while ((row >= 0) && (col < ncol)); row += 1; col += 3; /* & then sweep downward diagonally, inserting successive characters,... */ do { - if ((row >= 0) && (col < ncol) && array[row*ncol+col] == 0) - Utah(row,col,chr++); + if ((row >= 0) && (col < ncol) && array[row * ncol + col] == 0) + Utah(row, col, chr++); row += 2; col -= 2; } while ((row < nrow) && (col >= 0)); row += 3; col += 1; /* ... until the entire array is scanned */ } while ((row < nrow) || (col < ncol)); /* Lastly, if the lower righthand corner is untouched, fill in fixed pattern */ - if (array[nrow*ncol-1] == 0) { - array[nrow*ncol-1] = array[nrow*ncol-ncol-2] = 1; + if (array[nrow * ncol - 1] == 0) { + array[nrow * ncol - 1] = array[nrow * ncol - ncol - 2] = 1; } } } internal class ReedSolomon { - + private static readonly int[] log = { 0, 255, 1, 240, 2, 225, 241, 53, 3, 38, 226, 133, 242, 43, 54, 210, 4, 195, 39, 114, 227, 106, 134, 28, 243, 140, 44, 23, 55, 118, 211, 234, @@ -1236,41 +1656,41 @@ internal class ReedSolomon { 181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153, 132, 63, 96, 103, 82, 186 }; - + private static int[] GetPoly(int nc) { switch (nc) { - case 5: - return poly5; - case 7: - return poly7; - case 10: - return poly10; - case 11: - return poly11; - case 12: - return poly12; - case 14: - return poly14; - case 18: - return poly18; - case 20: - return poly20; - case 24: - return poly24; - case 28: - return poly28; - case 36: - return poly36; - case 42: - return poly42; - case 48: - return poly48; - case 56: - return poly56; - case 62: - return poly62; - case 68: - return poly68; + case 5: + return poly5; + case 7: + return poly7; + case 10: + return poly10; + case 11: + return poly11; + case 12: + return poly12; + case 14: + return poly14; + case 18: + return poly18; + case 20: + return poly20; + case 24: + return poly24; + case 28: + return poly28; + case 36: + return poly36; + case 42: + return poly42; + case 48: + return poly48; + case 56: + return poly56; + case 62: + return poly62; + case 68: + return poly68; } return null; } @@ -1278,11 +1698,11 @@ private static int[] GetPoly(int nc) { private static void ReedSolomonBlock(byte[] wd, int nd, byte[] ncout, int nc, int[] c) { int i, j, k; - for (i=0; i<=nc; i++) ncout[i] = 0; - for (i=0; i GetDocumentFonts(PdfReader reader, int page) { return fonts; } + internal static PdfDictionary createBuiltInFontDictionary(String name) { + PdfName fontName; + if (BuiltinFonts14.TryGetValue(name, out fontName)) { + return createBuiltInFontDictionary(fontName); + } + return null; + } + + private static PdfDictionary createBuiltInFontDictionary(PdfName name) { + if (name == null) { + return null; + } + PdfDictionary dictionary = new PdfDictionary(); + dictionary.Put(PdfName.TYPE, PdfName.FONT); + dictionary.Put(PdfName.BASEFONT, name); + dictionary.Put(PdfName.SUBTYPE, PdfName.TYPE1); + return dictionary; + } + /** * Gets the smallest box enclosing the character contours. It will return * null if the font has not the information or the character has no diff --git a/src/core/iTextSharp/text/pdf/CFFFontSubset.cs b/src/core/iTextSharp/text/pdf/CFFFontSubset.cs index 4c97ba5c2..6df069cd5 100644 --- a/src/core/iTextSharp/text/pdf/CFFFontSubset.cs +++ b/src/core/iTextSharp/text/pdf/CFFFontSubset.cs @@ -477,7 +477,7 @@ virtual protected void BuildNewLGSubrs(int Font) // Builds the New Local Subrs index NewSubrsIndexNonCID = BuildNewIndex(fonts[Font].SubrsOffsets,hSubrsUsedNonCID,RETURN_OP); //Builds the New Global Subrs index - NewGSubrsIndex = BuildNewIndex(gsubrOffsets,hGSubrsUsed,RETURN_OP); + NewGSubrsIndex = BuildNewIndexAndCopyAllGSubrs(gsubrOffsets,RETURN_OP); } /** @@ -972,6 +972,59 @@ virtual protected byte[] BuildNewIndex(int[] Offsets,Dictionary Used, return AssembleIndex(NewOffsets,NewObjects); } + /** + * Function builds the new offset array, object array and assembles the index. + * used for creating the glyph and subrs subsetted index + * @param Offsets the offset array of the original index + * @param OperatorForUnusedEntries the operator inserted into the data stream for unused entries + * @return the new index subset version + * @throws IOException + */ + virtual protected byte[] BuildNewIndexAndCopyAllGSubrs(int[] Offsets, byte OperatorForUnusedEntries) + { + int unusedCount = 0; + int Offset = 0; + int[] NewOffsets = new int[Offsets.Length]; + // Build the Offsets Array for the Subset + for (int i = 0; i < Offsets.Length - 1; ++i) + { + NewOffsets[i] = Offset; + Offset += Offsets[i + 1] - Offsets[i]; + } + // Else the same offset is kept in i+1 + NewOffsets[Offsets.Length - 1] = Offset; + unusedCount++; + + // Offset var determines the size of the object array + byte[] NewObjects = new byte[Offset + unusedCount]; + // Build the new Object array + int unusedOffset = 0; + for (int i = 0; i < Offsets.Length - 1; ++i) + { + int start = NewOffsets[i]; + int end = NewOffsets[i + 1]; + NewOffsets[i] = start + unusedOffset; + // If start != End then the Object is used + // So, we will copy the object data from the font file + if (start != end) + { + // All offsets are Global Offsets relative to the begining of the font file. + // Jump the file pointer to the start address to read from. + buf.Seek(Offsets[i]); + // Read from the buffer and write into the array at start. + buf.ReadFully(NewObjects, start + unusedOffset, end - start); + } + else + { + NewObjects[start + unusedOffset] = OperatorForUnusedEntries; + unusedOffset++; + } + } + NewOffsets[Offsets.Length - 1] += unusedOffset; + // Use AssembleIndex to build the index from the offset & object arrays + return AssembleIndex(NewOffsets, NewObjects); + } + /** * Function creates the new index, inserting the count,offsetsize,offset array * and object array. @@ -987,9 +1040,9 @@ virtual protected byte[] AssembleIndex(int[] NewOffsets,byte[] NewObjects) int Size = NewOffsets[NewOffsets.Length-1]; // Calc the Offsize byte Offsize; - if (Size <= 0xff) Offsize = 1; - else if (Size <= 0xffff) Offsize = 2; - else if (Size <= 0xffffff) Offsize = 3; + if (Size < 0xff) Offsize = 1; + else if (Size < 0xffff) Offsize = 2; + else if (Size < 0xffffff) Offsize = 3; else Offsize = 4; // The byte array for the new index. The size is calc by // Count=2, Offsize=1, OffsetArray = Offsize*(Count+1), The object array diff --git a/src/core/iTextSharp/text/pdf/FontSelector.cs b/src/core/iTextSharp/text/pdf/FontSelector.cs index ae426f2cb..9b31fa146 100644 --- a/src/core/iTextSharp/text/pdf/FontSelector.cs +++ b/src/core/iTextSharp/text/pdf/FontSelector.cs @@ -45,6 +45,7 @@ source product. using System.Globalization; using System.Text; using iTextSharp.text.error_messages; +using iTextSharp.text.log; namespace iTextSharp.text.pdf { /** Selects the appropriate fonts that contain the glyphs needed to @@ -56,8 +57,11 @@ namespace iTextSharp.text.pdf { * @author Paulo Soares */ public class FontSelector { + + private static readonly ILogger LOGGER = LoggerFactory.GetLogger(typeof(PdfSmartCopy)); protected List fonts = new List(); + protected List unsupportedFonts = new List(); protected Font currentFont = null; /** @@ -65,6 +69,10 @@ public class FontSelector { * @param font the Font */ virtual public void AddFont(Font font) { + if (!IsSupported(font)) { + unsupportedFonts.Add(font); + return; + } if (font.BaseFont != null) { fonts.Add(font); return; @@ -81,7 +89,7 @@ virtual public void AddFont(Font font) { * @return a Phrase with one or more chunks */ public virtual Phrase Process(String text) { - if (fonts.Count == 0) + if (GetSize() == 0) throw new ArgumentOutOfRangeException(MessageLocalization.GetComposedMessage("no.font.is.defined")); char[] cc = text.ToCharArray(); int len = cc.Length; @@ -95,7 +103,7 @@ public virtual Phrase Process(String text) { } } if (sb.Length > 0) { - Chunk ck = new Chunk(sb.ToString(), currentFont ?? fonts[0]); + Chunk ck = new Chunk(sb.ToString(), currentFont ?? GetFont(0)); ret.Add(ck); } return ret; @@ -111,8 +119,8 @@ protected virtual Chunk ProcessChar(char[] cc, int k, StringBuilder sb) { Font font = null; if(Utilities.IsSurrogatePair(cc, k)) { int u = Utilities.ConvertToUtf32(cc, k); - for(int f = 0; f < fonts.Count; ++f) { - font = fonts[f]; + for(int f = 0; f < GetSize(); ++f) { + font = GetFont(f); if (font.BaseFont.CharExists(u) || CharUnicodeInfo.GetUnicodeCategory(char.ConvertFromUtf32(u), 0) == UnicodeCategory.Format) { if (currentFont != font) { @@ -129,8 +137,8 @@ protected virtual Chunk ProcessChar(char[] cc, int k, StringBuilder sb) { } } else { - for(int f = 0; f < fonts.Count; ++f) { - font = fonts[f]; + for(int f = 0; f < GetSize(); ++f) { + font = GetFont(f); if(font.BaseFont.CharExists(c) || char.GetUnicodeCategory(c) == UnicodeCategory.Format) { if(currentFont != font) { if(sb.Length > 0 && currentFont != null) { @@ -147,5 +155,22 @@ protected virtual Chunk ProcessChar(char[] cc, int k, StringBuilder sb) { } return newChunk; } + + protected int GetSize() { + return fonts.Count + unsupportedFonts.Count; + } + + protected Font GetFont(int i) { + return i < fonts.Count ? fonts[i] : unsupportedFonts[i]; + } + + private bool IsSupported(Font font) { + BaseFont bf = font.BaseFont; + if (bf is TrueTypeFont && BaseFont.WINANSI.Equals(bf.Encoding) && !((TrueTypeFont)bf).IsWinAnsiSupported()) { + LOGGER.Warn(String.Format("cmap(1, 0) not found for TrueType Font {0}, it is required for WinAnsi encoding.", font)); + return false; + } + return true; + } } } diff --git a/src/core/iTextSharp/text/pdf/PdfContentByte.cs b/src/core/iTextSharp/text/pdf/PdfContentByte.cs index b82298f35..be3a26202 100644 --- a/src/core/iTextSharp/text/pdf/PdfContentByte.cs +++ b/src/core/iTextSharp/text/pdf/PdfContentByte.cs @@ -2729,7 +2729,7 @@ virtual public void Arc(double x1, double y1, double x2, double y2, double start */ public virtual void Ellipse(double x1, double y1, double x2, double y2) { - Ellipse((double)x1, (double)y1, (double)x2, (double)y2); + Ellipse((float)x1, (float)y1, (float)x2, (float)y2); } /** diff --git a/src/core/iTextSharp/text/pdf/PdfDictionary.cs b/src/core/iTextSharp/text/pdf/PdfDictionary.cs index 0e3d9f9c2..4d27ae548 100644 --- a/src/core/iTextSharp/text/pdf/PdfDictionary.cs +++ b/src/core/iTextSharp/text/pdf/PdfDictionary.cs @@ -44,6 +44,7 @@ source product. using System.IO; using System.Collections.Generic; using iTextSharp.text.pdf.intern; +using iTextSharp.text.error_messages; namespace iTextSharp.text.pdf { /** @@ -154,6 +155,8 @@ public override void ToPdf(PdfWriter writer, Stream os) { * @param value value of the entry (a PdfObject) */ virtual public void Put(PdfName key, PdfObject value) { + if (key == null) + throw new ArgumentNullException(MessageLocalization.GetComposedMessage("key.is.null")); if (value == null || value.IsNull()) hashMap.Remove(key); else @@ -168,6 +171,8 @@ virtual public void Put(PdfName key, PdfObject value) { * @param value value of the entry (a PdfObject) */ virtual public void PutEx(PdfName key, PdfObject value) { + if (key == null) + throw new ArgumentNullException(MessageLocalization.GetComposedMessage("key.is.null")); if (value == null) return; Put(key, value); @@ -202,7 +207,8 @@ virtual public void PutAll(PdfDictionary dic) { * @param key key of the entry (a PdfName) */ virtual public void Remove(PdfName key) { - hashMap.Remove(key); + if (key != null) + hashMap.Remove(key); } /** @@ -221,6 +227,9 @@ virtual public void Clear() { * @return the previous PdfObject corresponding with the key */ virtual public PdfObject Get(PdfName key) { + if (key == null) + return null; + PdfObject obj; if (hashMap.TryGetValue(key, out obj)) return obj; @@ -320,7 +329,7 @@ virtual public int Size { } virtual public bool Contains(PdfName key) { - return hashMap.ContainsKey(key); + return key != null && hashMap.ContainsKey(key); } public virtual Dictionary.Enumerator GetEnumerator() { diff --git a/src/core/iTextSharp/text/pdf/PdfPRow.cs b/src/core/iTextSharp/text/pdf/PdfPRow.cs index 26eed39c1..bdc22b008 100644 --- a/src/core/iTextSharp/text/pdf/PdfPRow.cs +++ b/src/core/iTextSharp/text/pdf/PdfPRow.cs @@ -649,7 +649,10 @@ virtual public void CopyRowContent(PdfPTable table, int idx) { * an empty row would result */ virtual public PdfPRow SplitRow(PdfPTable table, int rowIndex, float new_height) { - LOGGER.Info("Splitting " + rowIndex + " " + new_height); + if (LOGGER.IsLogging(Level.INFO)) + { + LOGGER.Info(String.Format("Splitting row {0} available height: {1}", rowIndex, new_height)); + } // second part of the row PdfPCell[] newCells = new PdfPCell[cells.Length]; float[] calHs = new float[cells.Length]; diff --git a/src/core/iTextSharp/text/pdf/PdfPTable.cs b/src/core/iTextSharp/text/pdf/PdfPTable.cs index 2c2920679..4eaa8c42b 100644 --- a/src/core/iTextSharp/text/pdf/PdfPTable.cs +++ b/src/core/iTextSharp/text/pdf/PdfPTable.cs @@ -787,9 +787,10 @@ virtual public float WriteSelectedRows(int colStart, int colEnd, int rowStart, i colEnd = totalCols; else colEnd = Math.Min(colEnd, totalCols); - - LOGGER.Info(String.Format("Writing row {0} to {1}; column {2} to {3}", rowStart, rowEnd, colStart, colEnd)); - + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("Writing row {0} to {1}; column {2} to {3}", rowStart, rowEnd, colStart, + colEnd)); + } float yPosStart = yPos; PdfPTableBody currentBlock = null; @@ -1920,7 +1921,9 @@ virtual public bool CellEnds() { * @since iText 5.4.3 */ virtual public FittingRows GetFittingRows(float availableHeight, int startIdx) { - LOGGER.Info(String.Format("GetFittingRows({0}, {1})", availableHeight, startIdx)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("GetFittingRows({0}, {1})", availableHeight, startIdx)); + } if (startIdx > 0 && startIdx < rows.Count) { System.Diagnostics.Debug.Assert(GetRow(startIdx).GetCells()[0] != null); // top left cell of current page may not be null } @@ -1946,8 +1949,9 @@ virtual public FittingRows GetFittingRows(float availableHeight, int startIdx) { state.ConsumeRowspan(completedRowsHeight, rowHeight); } else { state.BeginCell(cell, completedRowsHeight, rowHeight); - LOGGER.Info(String.Format("Height after BeginCell: {0} (cell: {1})", state.height, cell.CachedMaxHeight)); - + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("Height after BeginCell: {0} (cell: {1})", state.height, cell.CachedMaxHeight)); + } } if (state.CellEnds() && state.height > maxCompletedRowsHeight) { maxCompletedRowsHeight = state.height; diff --git a/src/core/iTextSharp/text/pdf/PdfReader.cs b/src/core/iTextSharp/text/pdf/PdfReader.cs index 97e72f603..2f0566e0a 100644 --- a/src/core/iTextSharp/text/pdf/PdfReader.cs +++ b/src/core/iTextSharp/text/pdf/PdfReader.cs @@ -909,7 +909,8 @@ private void ReadDecryptedDocObj() { else ownerPasswordUsed = true; } - } else if (filter.Equals(PdfName.PUBSEC)) { + } else if (filter.Equals(PdfName.PUBSEC)) { + decrypt.documentID = documentID; if ((cryptoMode & PdfWriter.ENCRYPTION_MASK) == PdfWriter.ENCRYPTION_AES_256) decrypt.SetKey(encryptionKey); else diff --git a/src/core/iTextSharp/text/pdf/PdfStamperImp.cs b/src/core/iTextSharp/text/pdf/PdfStamperImp.cs index 37d681edf..299b920f8 100644 --- a/src/core/iTextSharp/text/pdf/PdfStamperImp.cs +++ b/src/core/iTextSharp/text/pdf/PdfStamperImp.cs @@ -54,6 +54,7 @@ source product. using iTextSharp.text.pdf.collection; using iTextSharp.text.xml.xmp; using iTextSharp.text.error_messages; +using iTextSharp.text.io; using iTextSharp.xmp; using iTextSharp.xmp.options; @@ -85,6 +86,10 @@ public class PdfStamperImp : PdfWriter { protected int initialXrefSize; protected PdfAction openAction; + //Hash map of standard fonts used in flattening of annotations to prevent fonts duplication + private Dictionary builtInAnnotationFonts = new Dictionary(); + private static Dictionary fromShortToFullAnnotationFontNames = new Dictionary(); + private double[] DEFAULT_MATRIX = { 1, 0, 0, 1, 0, 0 }; protected ICounter COUNTER = CounterFactory.GetCounter(typeof(PdfStamper)); @@ -92,11 +97,30 @@ protected override ICounter GetCounter() { return COUNTER; } + private ILogger logger; + /* Flag which defines if PdfLayer objects from existing pdf have been already read. * If no new layers were registered and user didn't fetched layers explicitly via getPdfLayers() method * then original layers are never read - they are simply copied to the new document with whole original catalog. */ private bool originalLayersAreRead = false; + static PdfStamperImp() { + fromShortToFullAnnotationFontNames["CoBO"] = BaseFont.COURIER_BOLDOBLIQUE; + fromShortToFullAnnotationFontNames["CoBo"] = BaseFont.COURIER_BOLD; + fromShortToFullAnnotationFontNames["CoOb"] = BaseFont.COURIER_OBLIQUE; + fromShortToFullAnnotationFontNames["Cour"] = BaseFont.COURIER; + fromShortToFullAnnotationFontNames["HeBO"] = BaseFont.HELVETICA_BOLDOBLIQUE; + fromShortToFullAnnotationFontNames["HeBo"] = BaseFont.HELVETICA_BOLD; + fromShortToFullAnnotationFontNames["HeOb"] = BaseFont.HELVETICA_OBLIQUE; + fromShortToFullAnnotationFontNames["Helv"] = BaseFont.HELVETICA; + fromShortToFullAnnotationFontNames["Symb"] = BaseFont.SYMBOL; + fromShortToFullAnnotationFontNames["TiBI"] = BaseFont.TIMES_BOLDITALIC; + fromShortToFullAnnotationFontNames["TiBo"] = BaseFont.TIMES_BOLD; + fromShortToFullAnnotationFontNames["TiIt"] = BaseFont.TIMES_ITALIC; + fromShortToFullAnnotationFontNames["TiRo"] = BaseFont.TIMES_ROMAN; + fromShortToFullAnnotationFontNames["ZaDb"] = BaseFont.ZAPFDINGBATS; + } + /** Creates new PdfStamperImp. * @param reader the read PDF * @param os the output destination @@ -107,6 +131,7 @@ protected override ICounter GetCounter() { * @throws IOException */ internal protected PdfStamperImp(PdfReader reader, Stream os, char pdfVersion, bool append) : base(new PdfDocument(), os) { + this.logger = LoggerFactory.GetLogger(typeof(PdfStamper)); if (!reader.IsOpenedWithFullPermissions) throw new BadPasswordException(MessageLocalization.GetComposedMessage("pdfreader.not.opened.with.owner.password")); if (reader.Tampered) @@ -897,10 +922,14 @@ virtual internal protected void FlatFields() { PdfDictionary appDic = merged.GetAsDict(PdfName.AP); PdfObject as_n = null; if (appDic != null) { - as_n = appDic.GetAsStream(PdfName.N); + as_n = appDic.GetDirectObject(PdfName.N); + if (as_n == null) + as_n = appDic.GetAsStream(PdfName.N); if (as_n == null) as_n = appDic.GetAsDict(PdfName.N); } + //The rotation can be already applied if the appearance stream was written to document during setField method + bool applyRotation = false; if (acroFields.GenerateAppearances) { if (appDic == null || as_n == null) { try { @@ -915,6 +944,7 @@ virtual internal protected void FlatFields() { PdfArray bbox = stream.GetAsArray(PdfName.BBOX); PdfArray rect = merged.GetAsArray(PdfName.RECT); if (bbox != null && rect != null) { + applyRotation = true; float rectWidth = rect.GetAsNumber(2).FloatValue - rect.GetAsNumber(0).FloatValue; float bboxWidth = bbox.GetAsNumber(2).FloatValue - bbox.GetAsNumber(0).FloatValue; float rectHeight = rect.GetAsNumber(3).FloatValue - rect.GetAsNumber(1).FloatValue; @@ -1000,27 +1030,28 @@ virtual internal protected void FlatFields() { if (app != null) { Rectangle box = PdfReader.GetNormalizedRectangle(merged.GetAsArray(PdfName.RECT)); PdfContentByte cb = GetOverContent(page); - cb.SetLiteral("Q "); - /* - * Apply field rotation - */ - AffineTransform tf = new AffineTransform(); - double fieldRotation = 0; - if (merged.GetAsDict(PdfName.MK) != null) - { - if (merged.GetAsDict(PdfName.MK).Get(PdfName.R) != null) - { - fieldRotation = merged.GetAsDict(PdfName.MK).GetAsNumber(PdfName.R).DoubleValue; + if (applyRotation) { + /* + * Apply field rotation + */ + AffineTransform tf = new AffineTransform(); + double fieldRotation = 0; + if (merged.GetAsDict(PdfName.MK) != null) { + if (merged.GetAsDict(PdfName.MK).Get(PdfName.R) != null) { + fieldRotation = merged.GetAsDict(PdfName.MK).GetAsNumber(PdfName.R).DoubleValue; + } } + //Cast to radians + fieldRotation = fieldRotation*Math.PI/180; + //Clamp to [-2*Pi, 2*Pi] + fieldRotation = fieldRotation%(2*Math.PI); + //Calculate transformation matrix + tf = CalculateTemplateTransformationMatrix(tf, fieldRotation, box); + cb.AddTemplate(app, tf); + } else { + cb.AddTemplate(app, box.Left, box.Bottom); } - //Cast to radians - fieldRotation = fieldRotation * Math.PI / 180; - //Clamp to [-2*Pi, 2*Pi] - fieldRotation = fieldRotation % (2 * Math.PI); - //Calculate transformation matrix - tf = CalculateTemplateTransformationMatrix(tf, fieldRotation, box); - cb.AddTemplate(app, tf); cb.SetLiteral("q "); } } @@ -1197,12 +1228,13 @@ private void FlattenAnnotations(bool flattenFreeTextAnnotations) { continue; PdfDictionary annDic = (PdfDictionary) annoto; + PdfObject subType = annDic.Get(PdfName.SUBTYPE); if (flattenFreeTextAnnotations) { - if (!(annDic.Get(PdfName.SUBTYPE)).Equals(PdfName.FREETEXT)) { + if (!PdfName.FREETEXT.Equals(subType)) { continue; } } else { - if ((annDic.Get(PdfName.SUBTYPE)).Equals(PdfName.WIDGET)) { + if (PdfName.WIDGET.Equals(subType)) { // skip widgets continue; } @@ -1229,26 +1261,95 @@ private void FlattenAnnotations(bool flattenFreeTextAnnotations) { ((PdfDictionary) objReal).Put(PdfName.SUBTYPE, PdfName.FORM); app = new PdfAppearance((PdfIndirectReference) obj); } else { - if (objReal.IsDictionary()) { - PdfName as_p = appDic.GetAsName(PdfName.AS); - if (as_p != null) { - PdfIndirectReference iref = (PdfIndirectReference) ((PdfDictionary) objReal).Get(as_p); - if (iref != null) { - app = new PdfAppearance(iref); - if (iref.IsIndirect()) { - objReal = PdfReader.GetPdfObject(iref); - ((PdfDictionary) objReal).Put(PdfName.SUBTYPE, PdfName.FORM); + if (objReal != null) { + if (objReal.IsDictionary()) { + PdfName as_p = appDic.GetAsName(PdfName.AS); + if (as_p != null) { + PdfIndirectReference iref = + (PdfIndirectReference) ((PdfDictionary) objReal).Get(as_p); + if (iref != null) { + app = new PdfAppearance(iref); + if (iref.IsIndirect()) { + objReal = PdfReader.GetPdfObject(iref); + ((PdfDictionary) objReal).Put(PdfName.SUBTYPE, PdfName.FORM); + } } } } + } else { + if ( PdfName.FREETEXT.Equals(subType) ) { + PdfString defaultAppearancePdfString = annDic.GetAsString(PdfName.DA); + if (defaultAppearancePdfString != null) { + PdfString freeTextContent = annDic.GetAsString(PdfName.CONTENTS); + String defaultAppearanceString = defaultAppearancePdfString.ToString(); + + //It is not stated in spec, but acrobat seems to support standard font names in DA + //So we need to check if the font is built-in and specify it explicitly. + PdfIndirectReference fontReference = null; + PdfName pdfFontName = null; + try { + IRandomAccessSource source = new RandomAccessSourceFactory().CreateSource(defaultAppearancePdfString.GetBytes()); + PdfContentParser ps = new PdfContentParser(new PRTokeniser(new RandomAccessFileOrArray(source))); + List operands = new List(); + while (ps.Parse(operands).Count > 0) { + PdfLiteral op = (PdfLiteral) operands[operands.Count - 1]; + if (op.ToString().Equals("Tf")) { + pdfFontName = (PdfName) operands[0]; + String fontName = pdfFontName.ToString().Substring(1); + String fullName; + if (!fromShortToFullAnnotationFontNames.TryGetValue(fontName, out fullName)) { + fullName = fontName; + } + if (!builtInAnnotationFonts.TryGetValue(fullName, out fontReference)) { + PdfDictionary dic = BaseFont.createBuiltInFontDictionary(fullName); + if (dic != null) { + fontReference = AddToBody(dic).IndirectReference; + builtInAnnotationFonts[fullName] = fontReference; + } + } + } + } + } catch (Exception any) { + logger.Warn(MessageLocalization.GetComposedMessage("error.resolving.freetext.font")); + break; + } + + app = new PdfAppearance(this); + // it is unclear from spec were referenced from DA font should be (since annotations doesn't have DR), so in case it not built-in + // quickly and naively flattening the freetext annotation + if (fontReference != null) { + app.PageResources.AddFont(pdfFontName, fontReference); + } + app.SaveState(); + app.BeginText(); + app.SetLiteral(defaultAppearanceString); + app.SetLiteral("(" + freeTextContent.ToString() + ") Tj\n"); + app.EndText(); + app.RestoreState(); + } else { + // The DA entry is required for free text annotations + // Not throwing an exception as we don't want to stop the flow, result is that this annotation won't be flattened. + this.logger.Warn(MessageLocalization.GetComposedMessage("freetext.annotation.doesnt.contain.da")); + } + } else { + this.logger.Warn(MessageLocalization.GetComposedMessage("annotation.type.not.supported.flattening")); + } } } if (app != null) { Rectangle rect = PdfReader.GetNormalizedRectangle(annDic.GetAsArray(PdfName.RECT)); - Rectangle bbox = PdfReader.GetNormalizedRectangle(objDict.GetAsArray(PdfName.BBOX)); + Rectangle bbox = null; + + if (objDict != null) { + bbox = PdfReader.GetNormalizedRectangle(objDict.GetAsArray(PdfName.BBOX)); + } else { + bbox = new Rectangle(0, STANDARD_ENCRYPTION_40, rect.Width, rect.Height); + app.BoundingBox = bbox; + } + PdfContentByte cb = GetOverContent(page); cb.SetLiteral("Q "); - if (objDict.GetAsArray(PdfName.MATRIX) != null && + if (objDict != null && objDict.GetAsArray(PdfName.MATRIX) != null && !Util.ArraysAreEqual(DEFAULT_MATRIX, objDict.GetAsArray(PdfName.MATRIX).AsDoubleArray())) { double[] matrix = objDict.GetAsArray(PdfName.MATRIX).AsDoubleArray(); diff --git a/src/core/iTextSharp/text/pdf/TrueTypeFont.cs b/src/core/iTextSharp/text/pdf/TrueTypeFont.cs index 52febe553..e7cbd4fcb 100644 --- a/src/core/iTextSharp/text/pdf/TrueTypeFont.cs +++ b/src/core/iTextSharp/text/pdf/TrueTypeFont.cs @@ -1636,6 +1636,15 @@ protected override int[] GetRawCharBBox(int c, String name) { return bboxes[metric[0]]; } + /** + * Checks whether this font may be used with winansi encoding. + * + * @return true if the font can be correctly used with winansi encodings + */ + internal bool IsWinAnsiSupported() { + return cmap10 != null; + } + public int MaxGlyphId { get { return maxGlyphId; } } diff --git a/src/core/iTextSharp/text/pdf/XfaForm.cs b/src/core/iTextSharp/text/pdf/XfaForm.cs index 0d50a34f0..bf5148eed 100644 --- a/src/core/iTextSharp/text/pdf/XfaForm.cs +++ b/src/core/iTextSharp/text/pdf/XfaForm.cs @@ -120,8 +120,11 @@ public XfaForm(PdfReader reader) { } bout.Seek(0, SeekOrigin.Begin); XmlTextReader xtr = new XmlTextReader(bout); + xtr.XmlResolver = null; + xtr.ProhibitDtd = false; domDocument = new XmlDocument(); domDocument.PreserveWhitespace = true; + domDocument.XmlResolver = null; domDocument.Load(xtr); ExtractNodes(); } @@ -1105,6 +1108,7 @@ virtual public void FillXfaForm(XmlReader reader) { virtual public void FillXfaForm(XmlReader reader, bool readOnly) { XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; + doc.XmlResolver = null; doc.Load(reader); FillXfaForm(doc.DocumentElement); } diff --git a/src/core/iTextSharp/text/pdf/codec/TiffImage.cs b/src/core/iTextSharp/text/pdf/codec/TiffImage.cs index 841173660..ee62e253f 100644 --- a/src/core/iTextSharp/text/pdf/codec/TiffImage.cs +++ b/src/core/iTextSharp/text/pdf/codec/TiffImage.cs @@ -94,7 +94,10 @@ public static Image GetTiffImage(RandomAccessFileOrArray s, bool recoverFromImag TIFFDirectory dir = new TIFFDirectory(s, page - 1); if (dir.IsTagPresent(TIFFConstants.TIFFTAG_TILEWIDTH)) throw new ArgumentException(MessageLocalization.GetComposedMessage("tiles.are.not.supported")); - int compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION); + int compression = TIFFConstants.COMPRESSION_NONE; + if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COMPRESSION)) { + compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION); + } switch (compression) { case TIFFConstants.COMPRESSION_CCITTRLEW: case TIFFConstants.COMPRESSION_CCITTRLE: @@ -300,7 +303,10 @@ public static Image GetTiffImage(RandomAccessFileOrArray s, int page, bool direc protected static Image GetTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s) { int predictor = 1; TIFFLZWDecoder lzwDecoder = null; - int compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION); + int compression = TIFFConstants.COMPRESSION_NONE; + if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COMPRESSION)) { + compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION); + } switch (compression) { case TIFFConstants.COMPRESSION_NONE: case TIFFConstants.COMPRESSION_LZW: diff --git a/src/core/iTextSharp/text/pdf/security/LtvVerifier.cs b/src/core/iTextSharp/text/pdf/security/LtvVerifier.cs index 3e485ebe6..c49934953 100644 --- a/src/core/iTextSharp/text/pdf/security/LtvVerifier.cs +++ b/src/core/iTextSharp/text/pdf/security/LtvVerifier.cs @@ -88,7 +88,10 @@ public LtvVerifier(PdfReader reader) : base(null) { signatureName = names[names.Count - 1]; signDate = DateTime.Now; pkcs7 = CoversWholeDocument(); - LOGGER.Info(String.Format("Checking {0}signature {1}", pkcs7.IsTsp ? "document-level timestamp " : "", signatureName)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("Checking {0}signature {1}", pkcs7.IsTsp ? "document-level timestamp " : "", + signatureName)); + } } /** @@ -265,7 +268,10 @@ virtual public void SwitchToPreviousRevision() { names = fields.GetSignatureNames(); signatureName = names[names.Count - 1]; pkcs7 = CoversWholeDocument(); - LOGGER.Info(String.Format("Checking {0}signature {1}", pkcs7.IsTsp ? "document-level timestamp " : "", signatureName)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("Checking {0}signature {1}", pkcs7.IsTsp ? "document-level timestamp " : "", + signatureName)); + } } else { LOGGER.Info("No signatures in revision"); diff --git a/src/core/iTextSharp/text/pdf/security/OcspVerifier.cs b/src/core/iTextSharp/text/pdf/security/OcspVerifier.cs index ff472ec90..0d0abeadd 100644 --- a/src/core/iTextSharp/text/pdf/security/OcspVerifier.cs +++ b/src/core/iTextSharp/text/pdf/security/OcspVerifier.cs @@ -154,7 +154,9 @@ virtual public bool Verify(BasicOcspResp ocspResp, X509Certificate signCert, X50 else nextUpdateDate = nextUpdate.Value; if (signDate > nextUpdateDate) { - LOGGER.Info(String.Format("OCSP no longer valid: {0} after {1}", signDate, nextUpdateDate)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("OCSP no longer valid: {0} after {1}", signDate, nextUpdateDate)); + } continue; } // check the status of the certificate diff --git a/src/core/iTextSharp/text/pdf/security/TSAClientBouncyCastle.cs b/src/core/iTextSharp/text/pdf/security/TSAClientBouncyCastle.cs index ec7cb9985..c5a7fd400 100644 --- a/src/core/iTextSharp/text/pdf/security/TSAClientBouncyCastle.cs +++ b/src/core/iTextSharp/text/pdf/security/TSAClientBouncyCastle.cs @@ -92,6 +92,10 @@ public class TSAClientBouncyCastle : ITSAClient { /** Hash algorithm */ protected internal 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") @@ -135,6 +139,14 @@ virtual public void SetTSAInfo(ITSAInfoBouncyCastle tsaInfo) { this.tsaInfo = tsaInfo; } + public virtual String GetTSAReqPolicy() { + return tsaReqPolicy; + } + + public virtual void SetTSAReqPolicy(String tsaReqPolicy) { + this.tsaReqPolicy = tsaReqPolicy; + } + /** * Get the token size estimate. * Returned value reflects the result of the last succesfull call, padded @@ -163,6 +175,9 @@ public virtual byte[] GetTimeStampToken(byte[] imprint) { // Setup the time stamp request TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator(); tsqGenerator.SetCertReq(true); + if (!string.IsNullOrEmpty(tsaReqPolicy)) { + tsqGenerator.SetReqPolicy(tsaReqPolicy); + } // tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1"); BigInteger nonce = BigInteger.ValueOf(DateTime.Now.Ticks + Environment.TickCount); TimeStampRequest request = tsqGenerator.Generate(DigestAlgorithms.GetAllowedDigests(digestAlgorithm), imprint, nonce); diff --git a/src/core/iTextSharp/text/xml/xmp/XmpReader.cs b/src/core/iTextSharp/text/xml/xmp/XmpReader.cs index 56952489b..6d0e112be 100644 --- a/src/core/iTextSharp/text/xml/xmp/XmpReader.cs +++ b/src/core/iTextSharp/text/xml/xmp/XmpReader.cs @@ -86,8 +86,11 @@ public XmpReader(byte[] bytes) { bout.Write(bytes, 0, bytes.Length); bout.Seek(0, SeekOrigin.Begin); XmlTextReader xtr = new XmlTextReader(bout); + xtr.XmlResolver = null; + xtr.ProhibitDtd = false; domDocument = new XmlDocument(); domDocument.PreserveWhitespace = true; + domDocument.XmlResolver = null; domDocument.Load(xtr); } diff --git a/src/extras/iTextAsian/AssemblyInfo.cs b/src/extras/iTextAsian/AssemblyInfo.cs index 33dbf93d2..66031dd00 100644 --- a/src/extras/iTextAsian/AssemblyInfo.cs +++ b/src/extras/iTextAsian/AssemblyInfo.cs @@ -1,29 +1,13 @@ using System.Reflection; using System.Runtime.CompilerServices; -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// [assembly: AssemblyTitle("iTextAsian")] [assembly: AssemblyDescription("CJK CMAPS for iTextSharp.")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("Copyright (C) 1999-2012 by Bruno Lowagie and Paulo Soares. All Rights Reserved.")] +[assembly: AssemblyCompany("iText Group NV")] +[assembly: AssemblyProduct("iTextAsian")] +[assembly: AssemblyCopyright("Copyright (C) 1999-2017 by iText Group NV")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - [assembly: AssemblyVersion("2.1")] diff --git a/src/extras/iTextSharp.xtra/Properties/AssemblyInfo.cs b/src/extras/iTextSharp.xtra/Properties/AssemblyInfo.cs index 267ae0947..0d44a465d 100644 --- a/src/extras/iTextSharp.xtra/Properties/AssemblyInfo.cs +++ b/src/extras/iTextSharp.xtra/Properties/AssemblyInfo.cs @@ -6,10 +6,10 @@ [assembly: AssemblyDescription("Extra functionality for iTextSharp, a free PDF library ported from Java iText.")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] +[assembly: AssemblyCompany("iText Group NV")] [assembly: AssemblyProduct("iTextSharp.xtra")] [assembly: AssemblyCopyright("Copyright (C) 1999-2017 by iText Group NV")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("5.5.11")] +[assembly: AssemblyVersion("5.5.12")] diff --git a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/MCParser.cs b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/MCParser.cs index 54ece412f..17e791c42 100644 --- a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/MCParser.cs +++ b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/MCParser.cs @@ -215,7 +215,9 @@ virtual public void Parse(PdfDictionary page, PdfIndirectReference pageref) { baos.Close(); stream.SetData(baos.ToArray()); // showing how many items are left - LOGGER.Info(String.Format("There are {0} items left for processing", items.Count)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("There are {0} items left for processing", items.Count)); + } } /** @@ -226,7 +228,9 @@ virtual public void Parse(PdfDictionary page, PdfIndirectReference pageref) { virtual protected void DealWithXObj(PdfName xobj) { PdfDictionary dict = xobjects.GetAsStream(xobj); PdfNumber structParent = dict.GetAsNumber(PdfName.STRUCTPARENT); - LOGGER.Info(String.Format("Encountered StructParent {0} in content", structParent)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("Encountered StructParent {0} in content", structParent)); + } if(structParent == null) return; StructureItem item = items[0]; @@ -247,7 +251,9 @@ virtual protected void DealWithMcid(PdfNumber mcid) if (mcid == null) return; StructureItem item = items[0]; - LOGGER.Info(String.Format("Encountered MCID {0} in content, comparing with {1}", mcid, item)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("Encountered MCID {0} in content, comparing with {1}", mcid, item)); + } switch (item.CheckMCID(pageref.Number, mcid.IntValue)) { case 0: diff --git a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureItems.cs b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureItems.cs index 90a22fd1f..1c66a4ef2 100644 --- a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureItems.cs +++ b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureItems.cs @@ -104,7 +104,9 @@ public StructureItems(PdfReader reader) { */ protected virtual void ProcessStructElems(PdfDictionary structElem, PdfIndirectReference refa) { - LOGGER.Info(String.Format("addStructureItems({0}, {1})", structElem, refa)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("addStructureItems({0}, {1})", structElem, refa)); + } if (structElem == null) return; ProcessStructElemKids(structElem, refa, structElem.GetDirectObject(PdfName.K)); @@ -120,7 +122,9 @@ protected virtual void ProcessStructElems(PdfDictionary structElem, PdfIndirectR */ protected virtual void ProcessStructElemKids(PdfDictionary structElem, PdfIndirectReference refa, PdfObject objecta) { - LOGGER.Info(String.Format("addStructureItem({0}, {1}, {2})", structElem, refa, objecta)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("addStructureItem({0}, {1}, {2})", structElem, refa, objecta)); + } if (objecta == null) return; StructureItem item; diff --git a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureMCID.cs b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureMCID.cs index 4e6a8967b..2c169c5dc 100644 --- a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureMCID.cs +++ b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureMCID.cs @@ -58,7 +58,7 @@ public class StructureMCID : StructureItem { * @param obj an MCID */ public StructureMCID(PdfIndirectReference pg, PdfNumber mcid) { - this.pageref = pg.Number; + this.pageref = pg == null ? -1 : pg.Number; this.mcid = mcid.IntValue; } diff --git a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureObject.cs b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureObject.cs index d3fb03068..2f5e0794a 100644 --- a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureObject.cs +++ b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/mc/StructureObject.cs @@ -40,6 +40,7 @@ source product. For more information, please contact iText Software Corp. at this address: sales@itextpdf.com */ +using iTextSharp.text.exceptions; using System; namespace iTextSharp.text.pdf.mc @@ -68,7 +69,10 @@ public StructureObject(PdfDictionary structElem, PdfIndirectReference refa, PdfD this.refa = refa; 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("structparentid.not.found"); + this.structParent = sp.IntValue; PdfIndirectReference pg = dict.GetAsIndirectObject(PdfName.PG); if (pg == null) pg = structElem.GetAsIndirectObject(PdfName.PG); diff --git a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/ocg/OCGParser.cs b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/ocg/OCGParser.cs index 4b01c2a9c..f4f0bb4ca 100644 --- a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/ocg/OCGParser.cs +++ b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/ocg/OCGParser.cs @@ -191,8 +191,9 @@ public virtual void Parse(PRStream stream, PdfDictionary resources) { /// its operands /// protected internal static void ProcessOperator(OCGParser parser, PdfLiteral @operator, IList operands) { - PdfOperator op = operators[@operator.ToString()]; - if (op == null) { + PdfOperator op; + if (!operators.TryGetValue(@operator.ToString(), out op) || op == null) + { op = operators[DEFAULTOPERATOR]; } op.Process(parser, @operator, operands); diff --git a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/pdfcleanup/PdfCleanUpContentOperator.cs b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/pdfcleanup/PdfCleanUpContentOperator.cs index 190935264..c66d6c14d 100644 --- a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/pdfcleanup/PdfCleanUpContentOperator.cs +++ b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/pdfcleanup/PdfCleanUpContentOperator.cs @@ -160,8 +160,6 @@ public virtual void Invoke(PdfContentStreamProcessor pdfContentStreamProcessor, disableOutput = true; } } - } else if (lineStyleOperators.Contains(operatorStr)) { - disableOutput = true; } else if (textShowingOperators.Contains(operatorStr) && !AllChunksAreVisible(cleanUpStrategy.Chunks)) { disableOutput = true; diff --git a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/util/SmartPdfSplitter.cs b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/util/SmartPdfSplitter.cs index 9075ded1d..f4638dc7a 100644 --- a/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/util/SmartPdfSplitter.cs +++ b/src/extras/iTextSharp.xtra/iTextSharp/text/pdf/util/SmartPdfSplitter.cs @@ -62,7 +62,9 @@ public SmartPdfSplitter(PdfReader reader) { this.reader = reader; reader.Appendable = true; numberOfPages = reader.NumberOfPages; - LOGGER.Info(String.Format("Creating a splitter for a document with {0} pages", numberOfPages)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("Creating a splitter for a document with {0} pages", numberOfPages)); + } } public bool HasMorePages() { @@ -93,13 +95,17 @@ public bool Split(Stream os, long sizeInBytes) { page = counter.GetLength(resources); resources = counter.Resources; length += page + trailer + XrefLength(resources.Count); - LOGGER.Info(String.Format("Page {0}: Comparing {1} with {2}", currentPage, length, sizeInBytes)); - LOGGER.Info(String.Format(" page {0} trailer {1} xref {2}", page, trailer, XrefLength(resources.Count))); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("Page {0}: Comparing {1} with {2}", currentPage, length, sizeInBytes)); + LOGGER.Info(String.Format(" page {0} trailer {1} xref {2}", page, trailer, XrefLength(resources.Count))); + } if (!hasPage || length < sizeInBytes) { hasPage = true; copy.AddPage(copy.GetImportedPage(reader, currentPage)); length = copy.Os.Counter; - LOGGER.Info(String.Format("Size after adding page: {0}", length)); + if (LOGGER.IsLogging(Level.INFO)) { + LOGGER.Info(String.Format("Size after adding page: {0}", length)); + } if (length > sizeInBytes) overSized = true; currentPage++; } else { diff --git a/src/extras/itext-hyph-xml/AssemblyInfo.cs b/src/extras/itext-hyph-xml/AssemblyInfo.cs index 0f4d3c185..eef5a764e 100644 --- a/src/extras/itext-hyph-xml/AssemblyInfo.cs +++ b/src/extras/itext-hyph-xml/AssemblyInfo.cs @@ -1,56 +1,15 @@ using System.Reflection; using System.Runtime.CompilerServices; -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// [assembly: AssemblyTitle("itext-hyph-xml")] [assembly: AssemblyDescription("Hyphenation patterns for iTextSharp.")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("Copyright (C) 1999-2014 by Bruno Lowagie and Paulo Soares. All Rights Reserved.")] +[assembly: AssemblyCompany("iText Group NV")] +[assembly: AssemblyProduct("itext-hyph-xml")] +[assembly: AssemblyCopyright("Copyright (C) 1999-2017 by iText Group NV")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - [assembly: AssemblyVersion("2.0.0")] -// -// In order to sign your assembly you must specify a key to use. Refer to the -// Microsoft .NET Framework documentation for more information on assembly signing. -// -// Use the attributes below to control which key is used for signing. -// -// Notes: -// (*) If no key is specified, the assembly is not signed. -// (*) KeyName refers to a key that has been installed in the Crypto Service -// Provider (CSP) on your machine. KeyFile refers to a file which contains -// a key. -// (*) If the KeyFile and the KeyName values are both specified, the -// following processing occurs: -// (1) If the KeyName can be found in the CSP, that key is used. -// (2) If the KeyName does not exist and the KeyFile does exist, the key -// in the KeyFile is installed into the CSP and used. -// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. -// When specifying the KeyFile, the location of the KeyFile should be -// relative to the project output directory which is -// %Project Directory%\obj\. For example, if your KeyFile is -// located in the project directory, you would specify the AssemblyKeyFile -// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] -// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework -// documentation for more information on this. -// [assembly: AssemblyDelaySign(false)] diff --git a/src/extras/itextsharp.pdfa.tests/Properties/AssemblyInfo.cs b/src/extras/itextsharp.pdfa.tests/Properties/AssemblyInfo.cs index 66178c5ae..18d73fd6b 100644 --- a/src/extras/itextsharp.pdfa.tests/Properties/AssemblyInfo.cs +++ b/src/extras/itextsharp.pdfa.tests/Properties/AssemblyInfo.cs @@ -15,4 +15,4 @@ [assembly: Guid("ad182706-8617-4e07-ac63-2f1b88ebb671")] -[assembly: AssemblyVersion("5.5.11")] +[assembly: AssemblyVersion("5.5.12")] diff --git a/src/extras/itextsharp.pdfa.tests/resources/text/pdfa/cidset/cmp_cidFontCheckTest3.pdf b/src/extras/itextsharp.pdfa.tests/resources/text/pdfa/cidset/cmp_cidFontCheckTest3.pdf index 5a6ed8212..35577f861 100644 Binary files a/src/extras/itextsharp.pdfa.tests/resources/text/pdfa/cidset/cmp_cidFontCheckTest3.pdf and b/src/extras/itextsharp.pdfa.tests/resources/text/pdfa/cidset/cmp_cidFontCheckTest3.pdf differ diff --git a/src/extras/itextsharp.pdfa/Properties/AssemblyInfo.cs b/src/extras/itextsharp.pdfa/Properties/AssemblyInfo.cs index 2e28b981c..4ac6dc25c 100644 --- a/src/extras/itextsharp.pdfa/Properties/AssemblyInfo.cs +++ b/src/extras/itextsharp.pdfa/Properties/AssemblyInfo.cs @@ -15,4 +15,4 @@ [assembly: Guid("e1d9164b-61e9-4efa-9758-14406d5034cd")] -[assembly: AssemblyVersion("5.5.11")] +[assembly: AssemblyVersion("5.5.12")] diff --git a/src/extras/itextsharp.sandbox/Properties/AssemblyInfo.cs b/src/extras/itextsharp.sandbox/Properties/AssemblyInfo.cs index 1487d26af..b6bc44ce7 100644 --- a/src/extras/itextsharp.sandbox/Properties/AssemblyInfo.cs +++ b/src/extras/itextsharp.sandbox/Properties/AssemblyInfo.cs @@ -2,35 +2,18 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. [assembly: AssemblyTitle("itextsharp.sandbox")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] +[assembly: AssemblyCompany("iText Group NV")] [assembly: AssemblyProduct("itextsharp.sandbox")] -[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyCopyright("Copyright (C) 1999-2017 by iText Group NV")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] -// The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("230cab15-8151-4ddd-9578-97425dc9e99e")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/extras/itextsharp.tests/Properties/AssemblyInfo.cs b/src/extras/itextsharp.tests/Properties/AssemblyInfo.cs index 0569faa33..4adee0e94 100644 --- a/src/extras/itextsharp.tests/Properties/AssemblyInfo.cs +++ b/src/extras/itextsharp.tests/Properties/AssemblyInfo.cs @@ -15,4 +15,4 @@ [assembly: Guid("6d44f434-c50b-4232-87eb-853990beef3b")] -[assembly: AssemblyVersion("5.5.11")] +[assembly: AssemblyVersion("5.5.12")] diff --git a/src/extras/itextsharp.tests/iTextSharp/text/pdf/BarcodeDatamatrixTest.cs b/src/extras/itextsharp.tests/iTextSharp/text/pdf/BarcodeDatamatrixTest.cs new file mode 100644 index 000000000..10307f90f --- /dev/null +++ b/src/extras/itextsharp.tests/iTextSharp/text/pdf/BarcodeDatamatrixTest.cs @@ -0,0 +1,306 @@ +using itextsharp.tests.iTextSharp.testutils; +using iTextSharp.awt.geom; +using iTextSharp.testutils; +using iTextSharp.text; +using iTextSharp.text.pdf; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace itextsharp.tests.iTextSharp.text.pdf { + public class BarcodeDatamatrixTest { + private String cmpFolder = @"..\..\resources\text\pdf\BarcodeDatamatrix\"; + private String outFolder = @"BarcodeDatamatrix\"; + + [SetUp] + public void SetUp() { + Directory.CreateDirectory(outFolder); + TestResourceUtils.PurgeTempFiles(); + } + + [Test] + public void BarcodeTest01() { + 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 FileStream(outFolder + filename,FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 01")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.GREEN, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest02() { + String filename = "barcodeDataMatrix02.pdf"; + String code = "дима"; + String encoding = "UTF-8"; + + Document document = new Document(PageSize.A4); + PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 02")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Generate(code,encoding); + barcode.PlaceBarcode(cb, BaseColor.GREEN, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest03() { + String filename = "barcodeDataMatrix03.pdf"; + String code = "AbcdFFghijklmnopqrstuWXSQ"; + + Document document = new Document(PageSize.A4); + PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 03")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Width= 36; + barcode.Height = 12; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.BLACK, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest04() { + String filename = "barcodeDataMatrix04.pdf"; + String code = "01AbcdefgAbcdefg123451231231234"; + + Document document = new Document(PageSize.A4); + PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 04")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Width = 36; + barcode.Height = 12; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.BLACK, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest05() { + String filename = "barcodeDataMatrix05.pdf"; + String code = "aaabbbcccdddAAABBBAAABBaaabbbcccdddaaa"; + + Document document = new Document(PageSize.A4); + PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 05")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Width = 40; + barcode.Height = 40; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.BLACK, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest06() { + String filename = "barcodeDataMatrix06.pdf"; + String code = ">>>\r>>>THIS VERY TEXT>>\r>"; + + Document document = new Document(PageSize.A4); + PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 06")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Width = 36; + barcode.Height = 12; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.BLACK, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest07() { + 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 FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 07")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Options = BarcodeDatamatrix.DM_ASCII; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.GREEN, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest08() { + 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 FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 08")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Options = BarcodeDatamatrix.DM_C40; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.GREEN, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest09() { + 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 FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 09")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Options = BarcodeDatamatrix.DM_TEXT; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.GREEN, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest10() { + 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 FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 10")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Options = BarcodeDatamatrix.DM_B256; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.GREEN, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest11() { + 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 FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 11")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Options = BarcodeDatamatrix.DM_X12; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.GREEN, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest12() { + 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 FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 12")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Options = BarcodeDatamatrix.DM_EDIFACT; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.GREEN, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + [Test] + public void BarcodeTest13() { + 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 FileStream(outFolder + filename, FileMode.Create)); + document.Open(); + document.Add(new Paragraph("Datamatrix test 13")); + PdfContentByte cb = writer.DirectContent; + cb.ConcatCTM(AffineTransform.GetTranslateInstance(PageSize.A4.Width / 2 - 100, PageSize.A4.Height / 2 - 100)); + BarcodeDatamatrix barcode = new BarcodeDatamatrix(); + barcode.Options = BarcodeDatamatrix.DM_RAW; + barcode.Generate(code); + barcode.PlaceBarcode(cb, BaseColor.GREEN, 5, 5); + document.Close(); + + CompareDocuments(filename); + } + + + + /** + * Utility method that checks the created file against the cmp file + * @param file name of the output document + * @throws DocumentException + * @throws InterruptedException + * @throws IOException + */ + private void CompareDocuments(String file) { + // compare + CompareTool compareTool = new CompareTool(); + String errorMessage = compareTool.CompareByContent(outFolder + file, cmpFolder + file, outFolder, "diff"); + if (errorMessage != null) { + Assert.Fail(errorMessage); + } + } + + + } +} diff --git a/src/extras/itextsharp.tests/iTextSharp/text/pdf/FlatteningTest.cs b/src/extras/itextsharp.tests/iTextSharp/text/pdf/FlatteningTest.cs index 9162ca06e..f7d53888b 100644 --- a/src/extras/itextsharp.tests/iTextSharp/text/pdf/FlatteningTest.cs +++ b/src/extras/itextsharp.tests/iTextSharp/text/pdf/FlatteningTest.cs @@ -41,6 +41,7 @@ source product. address: sales@itextpdf.com */ using System; +using System.Collections.Generic; using System.IO; using iTextSharp.testutils; using iTextSharp.text; @@ -62,6 +63,35 @@ public void SetUp() { Directory.CreateDirectory(OUTPUT_FOLDER); } + [Test] + public virtual void TestFlatteningNewAppearances() { + String OUT = "tpl3_flattened.pdf"; + + PdfReader reader = new PdfReader(RESOURCES_FOLDER + "tpl3.pdf"); + AcroFields fields = reader.AcroFields; + if (fields != null && fields.Fields != null && fields.Fields.Count > 0) { + FileStream @out = null; + @out = new FileStream(OUTPUT_FOLDER + OUT, FileMode.Create); + PdfStamper stamp = new PdfStamper(reader, @out); + stamp.FormFlattening = true; + AcroFields form = stamp.AcroFields; + + foreach (KeyValuePair e in form.Fields) { + form.SetField(e.Key, e.Key); + } + + 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 virtual void TestFlattening() { const string INPUT_FOLDER = RESOURCES_FOLDER + "input/"; @@ -301,5 +331,29 @@ public void TestAnnotationFlatteningWithSkewAndRotation() { Assert.Fail(errorMessage); } } + + [Test] + public void TestRotatedFilledField() { + String file = "rotatedField.pdf"; + + PdfReader pdfReader = new PdfReader(RESOURCES_FOLDER + file); + PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(OUTPUT_FOLDER + file, FileMode.Create)); + + AcroFields fields = pdfStamper.AcroFields; + fields.SetField("Text1", "TEST"); + fields.GenerateAppearances = true; + + pdfStamper.FormFlattening = 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/src/extras/itextsharp.tests/iTextSharp/text/pdf/FreeTextFlatteningTest.cs b/src/extras/itextsharp.tests/iTextSharp/text/pdf/FreeTextFlatteningTest.cs new file mode 100644 index 000000000..7fa924996 --- /dev/null +++ b/src/extras/itextsharp.tests/iTextSharp/text/pdf/FreeTextFlatteningTest.cs @@ -0,0 +1,128 @@ +using System; +using System.IO; +using iTextSharp.testutils; +using iTextSharp.text.pdf; +using iTextSharp.text.pdf.parser; +using NUnit.Framework; + +namespace itextsharp.tests.iTextSharp.text.pdf { + [TestFixture] + public class FreeTextFlatteningTest { + private const String FOLDER = @"..\..\resources\text\pdf\FreeTextFlatteningTest\"; + private const String TARGET = @"FreeTextFlattening\"; + + [TestFixtureSetUp] + public static void setUp() { + Directory.CreateDirectory(TARGET); + } + + [Test] + public void FlattenCorrectlyTest() { + 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() { + CheckPageContent(FOLDER + "flattened.pdf"); + } + + [Test] + public void FlattenWithoutDA() { + String outputFile = TARGET + "freetext-flattened-no-da.pdf"; + + FlattenFreeText(FOLDER + "freetext-no-da.pdf", outputFile); + CheckAnnotationSize(outputFile, 1); + } + + [Test] + public void FlattenAndCheckCourier() { + String inputFile = FOLDER + "freetext-courier.pdf"; + String outputFile = TARGET + "freetext-courier-flattened.pdf"; + + FlattenFreeText(inputFile, outputFile); + CheckPageContent(outputFile); + } + + [Test] + public void FlattenAndCheckShortFontName() { + 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) { + FileStream fin = File.OpenRead(path); + CheckAnnotationSize(fin, expectedAnnotationsSize); + fin.Close(); + } + + private void CheckAnnotationSize(Stream inputStream, int expectedAnnotationsSize) { + PdfReader reader = new PdfReader(inputStream); + PdfDictionary pageDictionary = reader.GetPageN(1); + if ( pageDictionary.Contains(PdfName.ANNOTS )) { + PdfArray annotations = pageDictionary.GetAsArray(PdfName.ANNOTS); + Assert.True(annotations.Size == expectedAnnotationsSize); + } + } + + private void FlattenFreeText(String inputPath, String outputPath) { + FileStream fin = File.OpenRead(inputPath); + FileStream fout = File.Create(outputPath); + FlattenFreeText(fin, fout); + fin.Close(); + fout.Close(); + } + + private void FlattenFreeText(Stream inputStream, Stream outputStream) { + PdfReader reader = new PdfReader(inputStream); + PdfStamper stamper = new PdfStamper(reader, outputStream); + + stamper.FormFlattening = true; + stamper.FreeTextFlattening = true; + stamper.AnnotationFlattening = true; + + stamper.Close(); + } + + private void CheckPageContent(String path) { + PdfReader pdfReader = new PdfReader(path); + PdfDictionary pageDic = pdfReader.GetPageN(1); + + IRenderListener dummy = new DummyRenderListner(); + PdfContentStreamProcessor processor = new PdfContentStreamProcessor(dummy); + + PdfDictionary resourcesDic = pageDic.GetAsDict(PdfName.RESOURCES); + processor.ProcessContent(ContentByteUtils.GetContentBytesForPage(pdfReader, 1), resourcesDic); + pdfReader.Close(); + } + + private class DummyRenderListner : IRenderListener { + public void BeginTextBlock() { + } + + public void RenderText(TextRenderInfo renderInfo) { + } + + public void EndTextBlock() { + } + + public void RenderImage(ImageRenderInfo renderInfo) { + } + } + } +} \ No newline at end of file diff --git a/src/extras/itextsharp.tests/iTextSharp/text/pdf/PdfDictionaryTest.cs b/src/extras/itextsharp.tests/iTextSharp/text/pdf/PdfDictionaryTest.cs new file mode 100644 index 000000000..72cc3d99f --- /dev/null +++ b/src/extras/itextsharp.tests/iTextSharp/text/pdf/PdfDictionaryTest.cs @@ -0,0 +1,103 @@ +/* + 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 + */ +using System; +using iTextSharp.text.pdf; +using NUnit.Framework; + +namespace itextsharp.tests.iTextSharp.text.pdf +{ + public class PdfDictionaryTest + { + [Test] + public void PdfDictionaryGetReturnsNullIfKeyIsNull() + { + PdfDictionary dictionary = new PdfDictionary(); + + PdfObject value = dictionary.Get(null); + + Assert.IsNull(value); + } + + [Test] + public void PdfDictionaryContainsReturnsFalseIfKeyIsNull() + { + PdfDictionary dictionary = new PdfDictionary(); + + bool contained = dictionary.Contains(null); + + Assert.False(contained); + } + + [Test] + public void PdfDictionaryRemoveDoesNothingIfKeyIsNull() + { + PdfDictionary dictionary = new PdfDictionary(); + + dictionary.Remove(null); + } + + [Test] + public void PdfDictionaryPutThrowsExceptionIfKeyIsNull() + { + PdfDictionary dictionary = new PdfDictionary(); + + ArgumentNullException ex = Assert.Throws(delegate { + dictionary.Put(null, new PdfName("null")); + }); + + Assert.AreEqual(ex.ParamName, "key is null."); + } + + [Test] + public void PdfDictionaryPutExThrowsExceptionIfKeyIsNull() + { + PdfDictionary dictionary = new PdfDictionary(); + + ArgumentNullException ex = Assert.Throws(delegate { + dictionary.PutEx(null, new PdfName("null")); + }); + + Assert.AreEqual(ex.ParamName, "key is null."); + } + } +} diff --git a/src/extras/itextsharp.tests/iTextSharp/text/pdf/PdfEncryptionTest.cs b/src/extras/itextsharp.tests/iTextSharp/text/pdf/PdfEncryptionTest.cs index f3e1448ea..76ccf5af4 100644 --- a/src/extras/itextsharp.tests/iTextSharp/text/pdf/PdfEncryptionTest.cs +++ b/src/extras/itextsharp.tests/iTextSharp/text/pdf/PdfEncryptionTest.cs @@ -43,11 +43,21 @@ source product. using System; using System.Collections.Generic; using System.IO; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; using System.Text; +using System.util; using iTextSharp.testutils; using iTextSharp.text; using iTextSharp.text.pdf; +using iTextSharp.text.pdf.security; using NUnit.Framework; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.X509; +using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate; namespace itextsharp.tests.iTextSharp.text.pdf { class PdfEncryptionTest { @@ -109,5 +119,67 @@ public void ComputeUserPasswordAES256() { Assert.IsNull(password); } + + [Test] + public void EncryptWithCertificateAndSignTest() { + 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"); + + X509Certificate cert = new X509Certificate(); + cert.Import(SOURCE_FOLDER + "test.cer"); + + Pkcs12Store pkstore = new Pkcs12Store(new FileStream(SOURCE_FOLDER + "test.p12", FileMode.Open, FileAccess.Read), "kspass".ToCharArray()); + string pkalias = null; + foreach (object a in pkstore.Aliases) + { + pkalias = ((string)a); + if (pkstore.IsKeyEntry(pkalias)) + break; + } + ICipherParameters certpk = pkstore.GetKey(pkalias).Key; + + X509Certificate2 signCert = new X509Certificate2(SOURCE_FOLDER + "test.p12", "kspass"); + CertSign(signCert, new X509CertificateParser(), outPdf, new PdfReader(tmpPdf, Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(cert), certpk), "reason", "location"); + } + + public static void EncryptPdfWithCertificate(string sourceDocument, string targetDocument, string certPath) + { + X509Certificate chain = new X509Certificate(); + chain.Import(certPath); + Org.BouncyCastle.X509.X509Certificate cert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(chain); + Org.BouncyCastle.X509.X509Certificate[] certs = new Org.BouncyCastle.X509.X509Certificate[1] { cert }; + PdfReader reader = new PdfReader(sourceDocument); + PdfStamper st = new PdfStamper(reader, new FileStream(targetDocument, FileMode.Create, FileAccess.Write), '\0', false); + int[] x = new int[1]; + x[0] = PdfWriter.ALLOW_SCREENREADERS; + st.SetEncryption(certs, x, PdfWriter.STANDARD_ENCRYPTION_40); + st.Close(); + } + + private static void CertSign(X509Certificate2 cert, X509CertificateParser cp, string destinationPath, PdfReader reader, string reason, string location) + { + Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] + { + cp.ReadCertificate(cert.RawData) + }; + + IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-1"); + + using (FileStream fout = new FileStream(destinationPath, FileMode.Create, FileAccess.ReadWrite)) + { + using (PdfStamper stamper = PdfStamper.CreateSignature(reader, fout, '\0', null, true)) + { + PdfSignatureAppearance appearance = stamper.SignatureAppearance; + appearance.Reason = reason; + appearance.Location = location; + MakeSignature.SignDetached(appearance, externalSignature, chain, null, null, null, 0, + CryptoStandard.CADES); + stamper.Close(); + } + } + } } } \ No newline at end of file diff --git a/src/extras/itextsharp.tests/iTextSharp/text/pdf/pdfcleanup/PdfCleanUpProcessorTest.cs b/src/extras/itextsharp.tests/iTextSharp/text/pdf/pdfcleanup/PdfCleanUpProcessorTest.cs index 4b9e4a331..a9157da8a 100644 --- a/src/extras/itextsharp.tests/iTextSharp/text/pdf/pdfcleanup/PdfCleanUpProcessorTest.cs +++ b/src/extras/itextsharp.tests/iTextSharp/text/pdf/pdfcleanup/PdfCleanUpProcessorTest.cs @@ -85,6 +85,9 @@ private static object[] TestData() { List cleanUpLocations4 = new List(); cleanUpLocations4.Add(new PdfCleanUpLocation(1, new Rectangle(212, 394, 212 + 186, 394 + 170), null)); + List cleanUpLocations5 = new List(); + cleanUpLocations5.Add(new PdfCleanUpLocation(1, new Rectangle(0f, 0f, 595f, 680f), BaseColor.GRAY)); + return new object[] { new object[] {"page229.pdf", "page229_01.pdf", "cmp_page229_01.pdf", cleanUpLocations1}, new object[] {"page229-modified-Tc-Tw.pdf", "page229-modified-Tc-Tw.pdf", "cmp_page229-modified-Tc-Tw.pdf", cleanUpLocations1}, @@ -114,6 +117,8 @@ private static object[] TestData() { new object[] {"absentICentry.pdf", "absentICentry.pdf", "cmp_absentICentry.pdf", null}, new object[] {"lotOfDashes.pdf", "lotOfDashes.pdf", "cmp_lotOfDashes.pdf", null}, new object[] {"clipPathReduction.pdf", "clipPathReduction.pdf", "cmp_clipPathReduction.pdf", cleanUpLocations4}, + new object[] {"helloHelvetica.pdf", "helloHelvetica.pdf", "cmp_helloHelvetica.pdf", cleanUpLocations5}, + }; } diff --git a/src/extras/itextsharp.tests/itextsharp.tests(VS2010).csproj b/src/extras/itextsharp.tests/itextsharp.tests(VS2010).csproj index 2876b0b62..f57006116 100644 --- a/src/extras/itextsharp.tests/itextsharp.tests(VS2010).csproj +++ b/src/extras/itextsharp.tests/itextsharp.tests(VS2010).csproj @@ -91,6 +91,8 @@ + + diff --git a/src/extras/itextsharp.tests/itextsharp.tests.csproj b/src/extras/itextsharp.tests/itextsharp.tests.csproj index ba1778ac7..a0826de8f 100644 --- a/src/extras/itextsharp.tests/itextsharp.tests.csproj +++ b/src/extras/itextsharp.tests/itextsharp.tests.csproj @@ -76,6 +76,8 @@ + + diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix01.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix01.pdf new file mode 100644 index 000000000..b53726011 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix01.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix02.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix02.pdf new file mode 100644 index 000000000..5dc846727 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix02.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix03.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix03.pdf new file mode 100644 index 000000000..740750061 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix03.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix04.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix04.pdf new file mode 100644 index 000000000..a86f10695 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix04.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix05.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix05.pdf new file mode 100644 index 000000000..83fd8e609 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix05.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix06.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix06.pdf new file mode 100644 index 000000000..ccb863b12 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix06.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix07.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix07.pdf new file mode 100644 index 000000000..73d550125 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix07.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix08.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix08.pdf new file mode 100644 index 000000000..2a2fa1eaa Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix08.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix09.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix09.pdf new file mode 100644 index 000000000..a0e8800af Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix09.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix10.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix10.pdf new file mode 100644 index 000000000..ed1eb77ab Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix10.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix11.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix11.pdf new file mode 100644 index 000000000..209707226 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix11.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix12.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix12.pdf new file mode 100644 index 000000000..b41eb69d8 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix12.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix13.pdf b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix13.pdf new file mode 100644 index 000000000..1044b17bd Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/BarcodeDatamatrix/barcodeDataMatrix13.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/cmp_rotatedField.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/cmp_rotatedField.pdf new file mode 100644 index 000000000..2ca54188a Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/cmp_rotatedField.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/cmp_tpl3_flattened.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/cmp_tpl3_flattened.pdf new file mode 100644 index 000000000..0b680e7d6 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/cmp_tpl3_flattened.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/rotatedField.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/rotatedField.pdf new file mode 100644 index 000000000..6c9b469fa Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/rotatedField.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/tpl3.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/tpl3.pdf new file mode 100644 index 000000000..18bfb2442 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FlatteningTest/tpl3.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/cmp_freetext-times-short-flattened.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/cmp_freetext-times-short-flattened.pdf new file mode 100644 index 000000000..de5a4c423 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/cmp_freetext-times-short-flattened.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/flattened.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/flattened.pdf new file mode 100644 index 000000000..18db54b3b Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/flattened.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext-courier.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext-courier.pdf new file mode 100644 index 000000000..b6e6ffd97 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext-courier.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext-no-da.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext-no-da.pdf new file mode 100644 index 000000000..1305a4bcc Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext-no-da.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext-times-short.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext-times-short.pdf new file mode 100644 index 000000000..3c03454c1 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext-times-short.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext.pdf b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext.pdf new file mode 100644 index 000000000..36faaf32f Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/FreeTextFlatteningTest/freetext.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/PdfEncryptionTest/in.pdf b/src/extras/itextsharp.tests/resources/text/pdf/PdfEncryptionTest/in.pdf new file mode 100644 index 000000000..2f59b49e6 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/PdfEncryptionTest/in.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/PdfEncryptionTest/test.cer b/src/extras/itextsharp.tests/resources/text/pdf/PdfEncryptionTest/test.cer new file mode 100644 index 000000000..fbaad2b38 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/PdfEncryptionTest/test.cer differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/PdfEncryptionTest/test.p12 b/src/extras/itextsharp.tests/resources/text/pdf/PdfEncryptionTest/test.p12 new file mode 100644 index 000000000..dc8d37350 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/PdfEncryptionTest/test.p12 differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedBezier.pdf b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedBezier.pdf index 691293861..69785bcd9 100644 Binary files a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedBezier.pdf and b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedBezier.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedClosedRotatedTriangles.pdf b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedClosedRotatedTriangles.pdf index 68e64f629..27a64fbae 100644 Binary files a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedClosedRotatedTriangles.pdf and b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedClosedRotatedTriangles.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedStyledClosedBezier.pdf b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedStyledClosedBezier.pdf index 53954703a..cd850e07a 100644 Binary files a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedStyledClosedBezier.pdf and b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_dashedStyledClosedBezier.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_degenerateCases.pdf b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_degenerateCases.pdf index f587b7c97..a76b247d0 100644 Binary files a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_degenerateCases.pdf and b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_degenerateCases.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_helloHelvetica.pdf b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_helloHelvetica.pdf new file mode 100644 index 000000000..84fc609ba Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_helloHelvetica.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_lotOfDashes.pdf b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_lotOfDashes.pdf index cc3719a15..f7267c906 100644 Binary files a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_lotOfDashes.pdf and b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_lotOfDashes.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_miterTest.pdf b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_miterTest.pdf index 60047c023..f027f975f 100644 Binary files a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_miterTest.pdf and b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_miterTest.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_styledLineArts.pdf b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_styledLineArts.pdf index d5c081b14..e2b7952d7 100644 Binary files a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_styledLineArts.pdf and b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/cmp_styledLineArts.pdf differ diff --git a/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/helloHelvetica.pdf b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/helloHelvetica.pdf new file mode 100644 index 000000000..d42e7c258 Binary files /dev/null and b/src/extras/itextsharp.tests/resources/text/pdf/pdfcleanup/PdfCleanUpProcessorTest/helloHelvetica.pdf differ diff --git a/src/extras/itextsharp.xmlworker.tests/Properties/AssemblyInfo.cs b/src/extras/itextsharp.xmlworker.tests/Properties/AssemblyInfo.cs index ce012d6f5..2f4c41922 100644 --- a/src/extras/itextsharp.xmlworker.tests/Properties/AssemblyInfo.cs +++ b/src/extras/itextsharp.xmlworker.tests/Properties/AssemblyInfo.cs @@ -15,5 +15,5 @@ [assembly: Guid("f9ca61f8-a39e-4bcf-bf38-f58ea5f0b42a")] -[assembly: AssemblyVersion("5.5.11")] +[assembly: AssemblyVersion("5.5.12")] diff --git a/src/extras/itextsharp.xmlworker.tests/iTextSharp/tool/xml/BugRunnerTest.cs b/src/extras/itextsharp.xmlworker.tests/iTextSharp/tool/xml/BugRunnerTest.cs index f17442f7d..5c498d37d 100644 --- a/src/extras/itextsharp.xmlworker.tests/iTextSharp/tool/xml/BugRunnerTest.cs +++ b/src/extras/itextsharp.xmlworker.tests/iTextSharp/tool/xml/BugRunnerTest.cs @@ -65,6 +65,7 @@ virtual public void SetUp() { list.Add("3353957.html"); list.Add("ol-test.html"); list.Add("processing-instructions.html"); + list.Add("starcomments.html"); Directory.CreateDirectory(TARGET + "bugs/"); } diff --git a/src/extras/itextsharp.xmlworker.tests/itextsharp.xmlworker.tests(VS2010).csproj b/src/extras/itextsharp.xmlworker.tests/itextsharp.xmlworker.tests(VS2010).csproj index 3c1305cbb..0be0b3f4e 100644 --- a/src/extras/itextsharp.xmlworker.tests/itextsharp.xmlworker.tests(VS2010).csproj +++ b/src/extras/itextsharp.xmlworker.tests/itextsharp.xmlworker.tests(VS2010).csproj @@ -573,6 +573,7 @@ + diff --git a/src/extras/itextsharp.xmlworker.tests/itextsharp.xmlworker.tests.csproj b/src/extras/itextsharp.xmlworker.tests/itextsharp.xmlworker.tests.csproj index 6ed9ec91b..2d5dd17a5 100644 --- a/src/extras/itextsharp.xmlworker.tests/itextsharp.xmlworker.tests.csproj +++ b/src/extras/itextsharp.xmlworker.tests/itextsharp.xmlworker.tests.csproj @@ -571,6 +571,7 @@ + diff --git a/src/extras/itextsharp.xmlworker.tests/resources/bugs/starcomments.html b/src/extras/itextsharp.xmlworker.tests/resources/bugs/starcomments.html new file mode 100644 index 000000000..4bd41b8d3 --- /dev/null +++ b/src/extras/itextsharp.xmlworker.tests/resources/bugs/starcomments.html @@ -0,0 +1,12 @@ + + + + + + http://www.example.com/
* hi + + + + / + + \ No newline at end of file diff --git a/src/extras/itextsharp.xmlworker.tests/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/background_image_div01.html b/src/extras/itextsharp.xmlworker.tests/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/background_image_div01.html index 8c05c59e6..cd7488b2a 100644 --- a/src/extras/itextsharp.xmlworker.tests/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/background_image_div01.html +++ b/src/extras/itextsharp.xmlworker.tests/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/src/extras/itextsharp.xmlworker.tests/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/itext.png b/src/extras/itextsharp.xmlworker.tests/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/itext.png new file mode 100644 index 000000000..d961f4efa Binary files /dev/null and b/src/extras/itextsharp.xmlworker.tests/resources/com/itextpdf/tool/xml/examples/css/background/background_image/div/background_image_div01/itext.png differ diff --git a/src/extras/itextsharp.xmlworker/Properties/AssemblyInfo.cs b/src/extras/itextsharp.xmlworker/Properties/AssemblyInfo.cs index 424f2b46d..89b25f72d 100644 --- a/src/extras/itextsharp.xmlworker/Properties/AssemblyInfo.cs +++ b/src/extras/itextsharp.xmlworker/Properties/AssemblyInfo.cs @@ -16,4 +16,4 @@ [assembly: Guid("12ef9c6c-372c-4ba1-9104-89a92a97ff9a")] -[assembly: AssemblyVersion("5.5.11")] +[assembly: AssemblyVersion("5.5.12")] diff --git a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/html/head/Link.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/html/head/Link.cs index 3a10a18d1..4006bc0ac 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/html/head/Link.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/html/head/Link.cs @@ -71,9 +71,16 @@ public override IList Start(IWorkerContext ctx, 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) { - LOG.Warn(String.Format(LocaleMessages.GetInstance().GetMessage(LocaleMessages.CUSTOMCONTEXT_404_CONTINUE), typeof(CssResolverPipeline).FullName)); + if (LOG.IsLogging(Level.WARN)) { + LOG.Warn(String.Format( + LocaleMessages.GetInstance().GetMessage(LocaleMessages.CUSTOMCONTEXT_404_CONTINUE), + typeof(CssResolverPipeline).FullName)); + } } } } diff --git a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/html/head/Style.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/html/head/Style.cs index 7d1159213..f6f018cb0 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/html/head/Style.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/html/head/Style.cs @@ -78,7 +78,9 @@ public override IList Content(IWorkerContext ctx, Tag tag, String cont LOG.Trace(content); } } catch (NoCustomContextException) { - LOG.Warn(String.Format(LocaleMessages.GetInstance().GetMessage(LocaleMessages.CUSTOMCONTEXT_404_CONTINUE), typeof(CssResolverPipeline).FullName)); + if (LOG.IsLogging(Level.WARN)) { + LOG.Warn(String.Format(LocaleMessages.GetInstance().GetMessage(LocaleMessages.CUSTOMCONTEXT_404_CONTINUE), typeof(CssResolverPipeline).FullName)); + } } return new List(0); } diff --git a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/StateController.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/StateController.cs index bcc92b81a..bcdced25b 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/StateController.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/StateController.cs @@ -269,7 +269,7 @@ virtual public XMLParser UnquotedAttr() { * set Parser state to {@link StarCommentState}. * @return Parser */ - public XMLParser StarComment() + virtual public XMLParser StarComment() { return SetState(this.starComment); } @@ -278,9 +278,13 @@ public XMLParser StarComment() * set Parser state to {@link CloseStarCommentState}. * @return Parser */ - public XMLParser CloseStarComment() + virtual public XMLParser CloseStarComment() { return SetState(this.closeStarComment); } + + virtual public IState GetPreviousState() { + return previousState; + } } } diff --git a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/XMLParser.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/XMLParser.cs index d70020559..db2e3e4e5 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/XMLParser.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/XMLParser.cs @@ -65,6 +65,7 @@ public class XMLParser { private string text = null; private TagState tagState; private Encoding charset; + private bool decodeSpecialChars = true; /** * Constructs a default XMLParser ready for HTML/XHTML processing. @@ -343,9 +344,14 @@ virtual public XMLParserMemory Memory() { */ virtual public void StartElement() { CurrentTagState(TagState.OPEN); + String tagName = this.memory.GetCurrentTag(); + IDictionary attributes = this.memory.GetAttributes(); + if (tagName.StartsWith("?")) { + Memory().ProcessingInstruction().Length = 0; + } CallText(); foreach (IXMLParserListener l in listeners) { - l.StartElement(this.memory.GetCurrentTag(), this.memory.GetAttributes(), this.memory.GetNameSpace()); + l.StartElement(tagName, attributes, this.memory.GetNameSpace()); } this.memory.FlushNameSpace(); } @@ -432,6 +438,19 @@ private void CurrentTagState(TagState state) { virtual public void SetMonitor(IParserMonitor monitor) { this.monitor = monitor; } + + /** + * Determines whether special chars like > will be decoded + * @param decodeSpecialChars true to decode, false to not decode + */ + virtual public void SetDecodeSpecialChars(bool decodeSpecialChars) { + this.decodeSpecialChars = decodeSpecialChars; + } + + virtual public bool IsDecodeSpecialChars() { + return decodeSpecialChars; + } + /** * @return the current buffer as a String */ diff --git a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/XMLParserMemory.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/XMLParserMemory.cs index a6ec00bf5..e3459f88a 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/XMLParserMemory.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/XMLParserMemory.cs @@ -58,6 +58,7 @@ public class XMLParserMemory { private StringBuilder currentEntity = new StringBuilder(); private StringBuilder comment = new StringBuilder(); private StringBuilder baos = new StringBuilder(); + private StringBuilder processingInstruction = new StringBuilder(); private IDictionary attr; private String wsTag = ""; private String currentNameSpace = ""; @@ -98,6 +99,7 @@ virtual public void CurrentAttr(String attr) { virtual public bool HasCurrentAttribute() { return null != this.currentAttr; } + /** * Sets the current attribute value and adds the attribute (if it's not * null) to the attribute map. @@ -157,6 +159,14 @@ virtual public StringBuilder Comment() { return this.comment; } + /** + * Returns the xml processing instruction buffer + * @return processing instruction buffer + */ + virtual public StringBuilder ProcessingInstruction() { + return 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/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/InsideTagHTMLState.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/InsideTagHTMLState.cs index e178852bd..15f944401 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/InsideTagHTMLState.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/InsideTagHTMLState.cs @@ -95,7 +95,7 @@ virtual public void Process(char character) { } else if (character == '&') { this.parser.SelectState().SpecialChar(); } else { - if (character == '*' && this.parser.Memory().LastChar == '/') + if (this.parser.CurrentTag() == HTML.Tag.STYLE && character == '*' && this.parser.Memory().LastChar == '/' && parser.Memory().Current().Length > 0) { this.parser.SelectState().StarComment(); this.parser.Memory() diff --git a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/ProcessingInstructionEncounteredState.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/ProcessingInstructionEncounteredState.cs index bfa636d5a..1257d4ff4 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/ProcessingInstructionEncounteredState.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/ProcessingInstructionEncounteredState.cs @@ -71,6 +71,7 @@ public ProcessingInstructionEncounteredState(XMLParser parser) : base(parser) public override void Process(char character) { String tag = parser.BufferToString(); + this.parser.Memory().ProcessingInstruction().Append(character); if (name == null && Char.IsWhiteSpace(character)) { if (Char.IsWhiteSpace(character)) { diff --git a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/SelfClosingTagState.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/SelfClosingTagState.cs index 95c85c4ab..0294b581e 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/SelfClosingTagState.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/SelfClosingTagState.cs @@ -70,6 +70,8 @@ virtual public void Process(char character) { this.parser.Flush(); this.parser.Memory().FlushNameSpace(); this.parser.SelectState().InTag(); + } else if (this.parser.SelectState().GetPreviousState() is ProcessingInstructionEncounteredState) { + this.parser.Memory().ProcessingInstruction().Append(character); } } } diff --git a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/SpecialCharState.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/SpecialCharState.cs index b2df39fd7..b54ab8fcc 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/SpecialCharState.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/parser/state/SpecialCharState.cs @@ -58,7 +58,7 @@ public class SpecialCharState : IState { * @param parser the XMLParser */ public SpecialCharState(XMLParser parser) { - this.parser =parser; + this.parser = parser; } /* (non-Javadoc) @@ -70,7 +70,7 @@ virtual public void Process(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()) : (char)0; if (decoded == '\0') { parser.Append('&').Append(entity.ToString()).Append(';'); parser.Memory().LastChar = ';'; diff --git a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/pipeline/end/PdfWriterPipeline.cs b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/pipeline/end/PdfWriterPipeline.cs index 57ec99c27..76f7880e6 100644 --- a/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/pipeline/end/PdfWriterPipeline.cs +++ b/src/extras/itextsharp.xmlworker/iTextSharp/tool/xml/pipeline/end/PdfWriterPipeline.cs @@ -124,7 +124,7 @@ private void Write(IWorkerContext context, ProcessObject po) { if (writable is WritableElement) { foreach (IElement e in ((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()));